diff --git a/dist/cjs/plugins/replication-firestore/index.js b/dist/cjs/plugins/replication-firestore/index.js index 3435de7668e..6d2cd0efb2f 100644 --- a/dist/cjs/plugins/replication-firestore/index.js +++ b/dist/cjs/plugins/replication-firestore/index.js @@ -143,7 +143,8 @@ function replicateFirestore(options) { }, batchSize: (0, _index.ensureNotFalsy)(options.pull).batchSize, modifier: (0, _index.ensureNotFalsy)(options.pull).modifier, - stream$: pullStream$.asObservable() + stream$: pullStream$.asObservable(), + initialCheckpoint: options.pull.initialCheckpoint }; } var replicationPrimitivesPush; diff --git a/dist/cjs/plugins/replication-firestore/index.js.map b/dist/cjs/plugins/replication-firestore/index.js.map index c2cc4af9f46..cb01fb657c0 100644 --- a/dist/cjs/plugins/replication-firestore/index.js.map +++ b/dist/cjs/plugins/replication-firestore/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","names":["_index","require","_firestore","_index2","_index3","_index4","_rxjs","_firestoreHelper","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_firestoreTypes","RxFirestoreReplicationState","_RxReplicationState","firestore","replicationIdentifierHash","collection","pull","push","live","retryTime","autoStart","_this","_inheritsLoose2","default","RxReplicationState","replicateFirestore","options","addRxPlugin","RxDBLeaderElectionPlugin","pullStream$","Subject","replicationPrimitivesPull","waitForLeadership","serverTimestampField","primaryPath","schema","schemaPart","getSchemaByObjectPath","jsonSchema","includes","newRxError","field","pullFilters","filter","undefined","toArray","pullQuery","query","handler","lastPulledCheckpoint","batchSize","newerQuery","sameTimeQuery","lastServerTimestamp","isoStringToServerTimestamp","serverTimestamp","where","orderBy","limit","documentId","id","mustsReRun","useDocs","waitForPendingWrites","database","runTransaction","_tx","newerQueryResult","sameTimeQueryResult","Promise","all","getDocs","metadata","hasPendingWrites","ensureNotFalsy","docs","missingAmount","length","additionalDocs","slice","x","appendToArray","checkpoint","documents","lastDoc","lastOfArray","map","row","firestoreRowToDocData","newCheckpoint","serverTimestampToIsoString","data","ret","modifier","stream$","asObservable","replicationPrimitivesPush","pushFilter","rows","asyncFilter","newDocumentState","writeRowsById","docIds","docId","conflicts","getQuery","ids","docsInDbResult","getContentByIds","docsInDbById","docDataInDb","stripServerTimestampField","batch","writeBatch","hasWrite","entries","writeRow","docInDb","assumedMasterState","conflictHandler","isEqual","docRef","doc","writeDocData","flatClone","set","stripPrimaryKey","update","commit","replicationState","replicationIdentifier","startBefore","start","bind","cancelBefore","cancel","lastChangeQuery","unsubscribe","onSnapshot","_querySnapshot","reSync","error","subjects","next","errorToPlainJson","startReplicationOnLeaderShip"],"sources":["../../../../src/plugins/replication-firestore/index.ts"],"sourcesContent":["import {\n appendToArray,\n asyncFilter,\n ensureNotFalsy,\n errorToPlainJson,\n flatClone,\n lastOfArray,\n toArray\n} from '../../plugins/utils/index.ts';\n\nimport {\n doc,\n query,\n where,\n orderBy,\n limit,\n getDocs,\n onSnapshot,\n runTransaction,\n writeBatch,\n serverTimestamp,\n QueryDocumentSnapshot,\n waitForPendingWrites,\n documentId\n} from 'firebase/firestore';\n\nimport { RxDBLeaderElectionPlugin } from '../leader-election/index.ts';\nimport type {\n RxCollection,\n ReplicationPullOptions,\n ReplicationPushOptions,\n RxReplicationWriteToMasterRow,\n RxReplicationPullStreamItem\n} from '../../types/index.d.ts';\nimport {\n RxReplicationState,\n startReplicationOnLeaderShip\n} from '../replication/index.ts';\nimport {\n addRxPlugin,\n ById,\n getSchemaByObjectPath,\n newRxError,\n WithDeleted\n} from '../../index.ts';\n\nimport type {\n FirestoreCheckpointType,\n FirestoreOptions,\n SyncOptionsFirestore\n} from './firestore-types.ts';\nimport { Subject } from 'rxjs';\nimport {\n firestoreRowToDocData,\n getContentByIds,\n isoStringToServerTimestamp,\n serverTimestampToIsoString,\n stripPrimaryKey,\n stripServerTimestampField\n} from './firestore-helper.ts';\n\nexport * from './firestore-helper.ts';\nexport * from './firestore-types.ts';\n\nexport class RxFirestoreReplicationState extends RxReplicationState {\n constructor(\n public readonly firestore: FirestoreOptions,\n public readonly replicationIdentifierHash: string,\n public readonly collection: RxCollection,\n public readonly pull?: ReplicationPullOptions,\n public readonly push?: ReplicationPushOptions,\n public readonly live: boolean = true,\n public retryTime: number = 1000 * 5,\n public autoStart: boolean = true\n ) {\n super(\n replicationIdentifierHash,\n collection,\n '_deleted',\n pull,\n push,\n live,\n retryTime,\n autoStart\n );\n }\n}\n\nexport function replicateFirestore(\n options: SyncOptionsFirestore\n): RxFirestoreReplicationState {\n const collection: RxCollection = options.collection;\n addRxPlugin(RxDBLeaderElectionPlugin);\n const pullStream$: Subject> = new Subject();\n let replicationPrimitivesPull: ReplicationPullOptions | undefined;\n options.live = typeof options.live === 'undefined' ? true : options.live;\n options.waitForLeadership = typeof options.waitForLeadership === 'undefined' ? true : options.waitForLeadership;\n const serverTimestampField = typeof options.serverTimestampField === 'undefined' ? 'serverTimestamp' : options.serverTimestampField;\n options.serverTimestampField = serverTimestampField;\n const primaryPath = collection.schema.primaryPath;\n\n /**\n * The serverTimestampField MUST NOT be part of the collections RxJsonSchema.\n */\n const schemaPart = getSchemaByObjectPath(collection.schema.jsonSchema, serverTimestampField);\n if (\n schemaPart ||\n // also must not be nested.\n serverTimestampField.includes('.')\n ) {\n throw newRxError('RC6', {\n field: serverTimestampField,\n schema: collection.schema.jsonSchema\n });\n }\n\n const pullFilters = options.pull?.filter !== undefined\n ? toArray(options.pull.filter)\n : [];\n\n const pullQuery = query(options.firestore.collection, ...pullFilters);\n\n if (options.pull) {\n replicationPrimitivesPull = {\n async handler(\n lastPulledCheckpoint: FirestoreCheckpointType | undefined,\n batchSize: number\n ) {\n let newerQuery: ReturnType;\n let sameTimeQuery: ReturnType | undefined;\n\n if (lastPulledCheckpoint) {\n const lastServerTimestamp = isoStringToServerTimestamp(lastPulledCheckpoint.serverTimestamp);\n newerQuery = query(pullQuery,\n where(serverTimestampField, '>', lastServerTimestamp),\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n sameTimeQuery = query(pullQuery,\n where(serverTimestampField, '==', lastServerTimestamp),\n where(documentId(), '>', lastPulledCheckpoint.id),\n orderBy(documentId(), 'asc'),\n limit(batchSize)\n );\n } else {\n newerQuery = query(pullQuery,\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n }\n\n let mustsReRun = true;\n let useDocs: QueryDocumentSnapshot[] = [];\n while (mustsReRun) {\n /**\n * Local writes that have not been persisted to the server\n * are in pending state and do not have a correct serverTimestamp set.\n * We have to ensure we only use document states that are in sync with the server.\n * @link https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b\n */\n await waitForPendingWrites(options.firestore.database);\n await runTransaction(options.firestore.database, async (_tx) => {\n useDocs = [];\n const [\n newerQueryResult,\n sameTimeQueryResult\n ] = await Promise.all([\n getDocs(newerQuery),\n sameTimeQuery ? getDocs(sameTimeQuery) : undefined\n ]);\n\n if (\n newerQueryResult.metadata.hasPendingWrites ||\n (sameTimeQuery && ensureNotFalsy(sameTimeQueryResult).metadata.hasPendingWrites)\n ) {\n return;\n } else {\n mustsReRun = false;\n\n if (sameTimeQuery) {\n useDocs = ensureNotFalsy(sameTimeQueryResult).docs as any;\n }\n const missingAmount = batchSize - useDocs.length;\n if (missingAmount > 0) {\n const additionalDocs = newerQueryResult.docs.slice(0, missingAmount).filter(x => !!x);\n appendToArray(useDocs, additionalDocs);\n }\n }\n });\n }\n\n if (useDocs.length === 0) {\n return {\n checkpoint: lastPulledCheckpoint ?? null,\n documents: []\n };\n }\n const lastDoc = ensureNotFalsy(lastOfArray(useDocs));\n const documents: WithDeleted[] = useDocs\n .map(row => firestoreRowToDocData(\n serverTimestampField,\n primaryPath,\n row\n ));\n const newCheckpoint: FirestoreCheckpointType = {\n id: lastDoc.id,\n serverTimestamp: serverTimestampToIsoString(serverTimestampField, lastDoc.data())\n };\n const ret = {\n documents: documents,\n checkpoint: newCheckpoint\n };\n return ret;\n },\n batchSize: ensureNotFalsy(options.pull).batchSize,\n modifier: ensureNotFalsy(options.pull).modifier,\n stream$: pullStream$.asObservable()\n };\n }\n\n let replicationPrimitivesPush: ReplicationPushOptions | undefined;\n if (options.push) {\n const pushFilter = options.push?.filter;\n replicationPrimitivesPush = {\n async handler(\n rows: RxReplicationWriteToMasterRow[]\n ) {\n if (pushFilter !== undefined) {\n rows = await asyncFilter(rows, (row) => pushFilter(row.newDocumentState));\n }\n\n const writeRowsById: ById> = {};\n const docIds: string[] = rows.map(row => {\n const docId = (row.newDocumentState as any)[primaryPath];\n writeRowsById[docId] = row;\n return docId;\n });\n await waitForPendingWrites(options.firestore.database);\n let conflicts: WithDeleted[] = [];\n\n /**\n * Everything must run INSIDE of the transaction\n * because on tx-errors, firebase will re-run the transaction on some cases.\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#transaction_failure\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions\n */\n await runTransaction(options.firestore.database, async (_tx) => {\n conflicts = []; // reset in case the tx has re-run.\n /**\n * @link https://stackoverflow.com/a/48423626/3443137\n */\n\n const getQuery = (ids: string[]) => {\n return getDocs(\n query(\n options.firestore.collection,\n where(documentId(), 'in', ids)\n )\n );\n };\n\n const docsInDbResult = await getContentByIds(docIds, getQuery);\n\n const docsInDbById: ById = {};\n docsInDbResult.forEach(row => {\n const docDataInDb = stripServerTimestampField(serverTimestampField, row.data());\n const docId = row.id;\n (docDataInDb as any)[primaryPath] = docId;\n docsInDbById[docId] = docDataInDb;\n });\n\n /**\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n */\n const batch = writeBatch(options.firestore.database);\n let hasWrite = false;\n await Promise.all(\n Object.entries(writeRowsById).map(async ([docId, writeRow]) => {\n const docInDb: RxDocType | undefined = docsInDbById[docId];\n\n if (\n docInDb &&\n (\n !writeRow.assumedMasterState ||\n collection.conflictHandler.isEqual(docInDb as any, writeRow.assumedMasterState, 'replication-firestore-push') === false\n )\n ) {\n // conflict\n conflicts.push(docInDb as any);\n } else {\n // no conflict\n hasWrite = true;\n const docRef = doc(options.firestore.collection, docId);\n const writeDocData = flatClone(writeRow.newDocumentState);\n (writeDocData as any)[serverTimestampField] = serverTimestamp();\n if (!docInDb) {\n // insert\n batch.set(docRef, stripPrimaryKey(primaryPath, writeDocData));\n } else {\n // update\n batch.update(docRef, stripPrimaryKey(primaryPath, writeDocData));\n }\n }\n })\n );\n\n if (hasWrite) {\n await batch.commit();\n }\n });\n await waitForPendingWrites(options.firestore.database);\n return conflicts;\n },\n batchSize: options.push.batchSize,\n modifier: options.push.modifier\n };\n }\n\n\n const replicationState = new RxFirestoreReplicationState(\n options.firestore,\n options.replicationIdentifier,\n collection,\n replicationPrimitivesPull,\n replicationPrimitivesPush,\n options.live,\n options.retryTime,\n options.autoStart\n );\n\n /**\n * Use long polling to get live changes for the pull.stream$\n */\n if (options.live && options.pull) {\n const startBefore = replicationState.start.bind(replicationState);\n const cancelBefore = replicationState.cancel.bind(replicationState);\n replicationState.start = () => {\n const lastChangeQuery = query(\n pullQuery,\n orderBy(serverTimestampField, 'desc'),\n limit(1)\n );\n const unsubscribe = onSnapshot(\n lastChangeQuery,\n (_querySnapshot) => {\n /**\n * There is no good way to observe the event stream in firestore.\n * So instead we listen to any write to the collection\n * and then emit a 'RESYNC' flag.\n */\n replicationState.reSync();\n },\n (error) => {\n replicationState.subjects.error.next(\n newRxError('RC_STREAM', { error: errorToPlainJson(error) })\n );\n }\n );\n replicationState.cancel = () => {\n unsubscribe();\n return cancelBefore();\n };\n return startBefore();\n };\n }\n\n startReplicationOnLeaderShip(options.waitForLeadership, replicationState);\n\n return replicationState;\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAUA,IAAAC,UAAA,GAAAD,OAAA;AAgBA,IAAAE,OAAA,GAAAF,OAAA;AAQA,IAAAG,OAAA,GAAAH,OAAA;AAIA,IAAAI,OAAA,GAAAJ,OAAA;AAaA,IAAAK,KAAA,GAAAL,OAAA;AACA,IAAAM,gBAAA,GAAAN,OAAA;AASAO,MAAA,CAAAC,IAAA,CAAAF,gBAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,gBAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,gBAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AACA,IAAAS,eAAA,GAAAnB,OAAA;AAAAO,MAAA,CAAAC,IAAA,CAAAW,eAAA,EAAAV,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAS,eAAA,CAAAT,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,eAAA,CAAAT,GAAA;IAAA;EAAA;AAAA;AAAqC,IAExBU,2BAA2B,GAAAL,OAAA,CAAAK,2BAAA,0BAAAC,mBAAA;EACpC,SAAAD,4BACoBE,SAAsC,EACtCC,yBAAiC,EACjCC,UAAmC,EACnCC,IAAiE,EACjEC,IAAwC,EACxCC,IAAa,GAAG,IAAI,EAC7BC,SAAiB,GAAG,IAAI,GAAG,CAAC,EAC5BC,SAAkB,GAAG,IAAI,EAClC;IAAA,IAAAC,KAAA;IACEA,KAAA,GAAAT,mBAAA,CAAAR,IAAA,OACIU,yBAAyB,EACzBC,UAAU,EACV,UAAU,EACVC,IAAI,EACJC,IAAI,EACJC,IAAI,EACJC,SAAS,EACTC,SACJ,CAAC;IAACC,KAAA,CAlBcR,SAAsC,GAAtCA,SAAsC;IAAAQ,KAAA,CACtCP,yBAAiC,GAAjCA,yBAAiC;IAAAO,KAAA,CACjCN,UAAmC,GAAnCA,UAAmC;IAAAM,KAAA,CACnCL,IAAiE,GAAjEA,IAAiE;IAAAK,KAAA,CACjEJ,IAAwC,GAAxCA,IAAwC;IAAAI,KAAA,CACxCH,IAAa,GAAbA,IAAa;IAAAG,KAAA,CACtBF,SAAiB,GAAjBA,SAAiB;IAAAE,KAAA,CACjBD,SAAkB,GAAlBA,SAAkB;IAAA,OAAAC,KAAA;EAY7B;EAAC,IAAAC,eAAA,CAAAC,OAAA,EAAAZ,2BAAA,EAAAC,mBAAA;EAAA,OAAAD,2BAAA;AAAA,EArBuDa,0BAAkB;AAwBvE,SAASC,kBAAkBA,CAC9BC,OAAwC,EACF;EACtC,IAAMX,UAAmC,GAAGW,OAAO,CAACX,UAAU;EAC9D,IAAAY,mBAAW,EAACC,gCAAwB,CAAC;EACrC,IAAMC,WAAqF,GAAG,IAAIC,aAAO,CAAC,CAAC;EAC3G,IAAIC,yBAAiG;EACrGL,OAAO,CAACR,IAAI,GAAG,OAAOQ,OAAO,CAACR,IAAI,KAAK,WAAW,GAAG,IAAI,GAAGQ,OAAO,CAACR,IAAI;EACxEQ,OAAO,CAACM,iBAAiB,GAAG,OAAON,OAAO,CAACM,iBAAiB,KAAK,WAAW,GAAG,IAAI,GAAGN,OAAO,CAACM,iBAAiB;EAC/G,IAAMC,oBAAoB,GAAG,OAAOP,OAAO,CAACO,oBAAoB,KAAK,WAAW,GAAG,iBAAiB,GAAGP,OAAO,CAACO,oBAAoB;EACnIP,OAAO,CAACO,oBAAoB,GAAGA,oBAAoB;EACnD,IAAMC,WAAW,GAAGnB,UAAU,CAACoB,MAAM,CAACD,WAAW;;EAEjD;AACJ;AACA;EACI,IAAME,UAAU,GAAG,IAAAC,6BAAqB,EAACtB,UAAU,CAACoB,MAAM,CAACG,UAAU,EAAEL,oBAAoB,CAAC;EAC5F,IACIG,UAAU;EACV;EACAH,oBAAoB,CAACM,QAAQ,CAAC,GAAG,CAAC,EACpC;IACE,MAAM,IAAAC,kBAAU,EAAC,KAAK,EAAE;MACpBC,KAAK,EAAER,oBAAoB;MAC3BE,MAAM,EAAEpB,UAAU,CAACoB,MAAM,CAACG;IAC9B,CAAC,CAAC;EACN;EAEA,IAAMI,WAAW,GAAGhB,OAAO,CAACV,IAAI,EAAE2B,MAAM,KAAKC,SAAS,GAChD,IAAAC,cAAO,EAACnB,OAAO,CAACV,IAAI,CAAC2B,MAAM,CAAC,GAC5B,EAAE;EAER,IAAMG,SAAS,GAAG,IAAAC,gBAAK,EAACrB,OAAO,CAACb,SAAS,CAACE,UAAU,EAAE,GAAG2B,WAAW,CAAC;EAErE,IAAIhB,OAAO,CAACV,IAAI,EAAE;IACde,yBAAyB,GAAG;MACxB,MAAMiB,OAAOA,CACTC,oBAAyD,EACzDC,SAAiB,EACnB;QACE,IAAIC,UAAoC;QACxC,IAAIC,aAAmD;QAEvD,IAAIH,oBAAoB,EAAE;UACtB,IAAMI,mBAAmB,GAAG,IAAAC,2CAA0B,EAACL,oBAAoB,CAACM,eAAe,CAAC;UAC5FJ,UAAU,GAAG,IAAAJ,gBAAK,EAACD,SAAS,EACxB,IAAAU,gBAAK,EAACvB,oBAAoB,EAAE,GAAG,EAAEoB,mBAAmB,CAAC,EACrD,IAAAI,kBAAO,EAACxB,oBAAoB,EAAE,KAAK,CAAC,EACpC,IAAAyB,gBAAK,EAACR,SAAS,CACnB,CAAC;UACDE,aAAa,GAAG,IAAAL,gBAAK,EAACD,SAAS,EAC3B,IAAAU,gBAAK,EAACvB,oBAAoB,EAAE,IAAI,EAAEoB,mBAAmB,CAAC,EACtD,IAAAG,gBAAK,EAAC,IAAAG,qBAAU,EAAC,CAAC,EAAE,GAAG,EAAEV,oBAAoB,CAACW,EAAE,CAAC,EACjD,IAAAH,kBAAO,EAAC,IAAAE,qBAAU,EAAC,CAAC,EAAE,KAAK,CAAC,EAC5B,IAAAD,gBAAK,EAACR,SAAS,CACnB,CAAC;QACL,CAAC,MAAM;UACHC,UAAU,GAAG,IAAAJ,gBAAK,EAACD,SAAS,EACxB,IAAAW,kBAAO,EAACxB,oBAAoB,EAAE,KAAK,CAAC,EACpC,IAAAyB,gBAAK,EAACR,SAAS,CACnB,CAAC;QACL;QAEA,IAAIW,UAAU,GAAG,IAAI;QACrB,IAAIC,OAA2C,GAAG,EAAE;QACpD,OAAOD,UAAU,EAAE;UACf;AACpB;AACA;AACA;AACA;AACA;UACoB,MAAM,IAAAE,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;UACtD,MAAM,IAAAC,yBAAc,EAACvC,OAAO,CAACb,SAAS,CAACmD,QAAQ,EAAE,MAAOE,GAAG,IAAK;YAC5DJ,OAAO,GAAG,EAAE;YACZ,IAAM,CACFK,gBAAgB,EAChBC,mBAAmB,CACtB,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAClB,IAAAC,kBAAO,EAACpB,UAAU,CAAC,EACnBC,aAAa,GAAG,IAAAmB,kBAAO,EAACnB,aAAa,CAAC,GAAGR,SAAS,CACrD,CAAC;YAEF,IACIuB,gBAAgB,CAACK,QAAQ,CAACC,gBAAgB,IACzCrB,aAAa,IAAI,IAAAsB,qBAAc,EAACN,mBAAmB,CAAC,CAACI,QAAQ,CAACC,gBAAiB,EAClF;cACE;YACJ,CAAC,MAAM;cACHZ,UAAU,GAAG,KAAK;cAElB,IAAIT,aAAa,EAAE;gBACfU,OAAO,GAAG,IAAAY,qBAAc,EAACN,mBAAmB,CAAC,CAACO,IAAW;cAC7D;cACA,IAAMC,aAAa,GAAG1B,SAAS,GAAGY,OAAO,CAACe,MAAM;cAChD,IAAID,aAAa,GAAG,CAAC,EAAE;gBACnB,IAAME,cAAc,GAAGX,gBAAgB,CAACQ,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEH,aAAa,CAAC,CAACjC,MAAM,CAACqC,CAAC,IAAI,CAAC,CAACA,CAAC,CAAC;gBACrF,IAAAC,oBAAa,EAACnB,OAAO,EAAEgB,cAAc,CAAC;cAC1C;YACJ;UACJ,CAAC,CAAC;QACN;QAEA,IAAIhB,OAAO,CAACe,MAAM,KAAK,CAAC,EAAE;UACtB,OAAO;YACHK,UAAU,EAAEjC,oBAAoB,IAAI,IAAI;YACxCkC,SAAS,EAAE;UACf,CAAC;QACL;QACA,IAAMC,OAAO,GAAG,IAAAV,qBAAc,EAAC,IAAAW,kBAAW,EAACvB,OAAO,CAAC,CAAC;QACpD,IAAMqB,SAAmC,GAAGrB,OAAO,CAC9CwB,GAAG,CAACC,GAAG,IAAI,IAAAC,sCAAqB,EAC7BvD,oBAAoB,EACpBC,WAAW,EACXqD,GACJ,CAAC,CAAC;QACN,IAAME,aAAsC,GAAG;UAC3C7B,EAAE,EAAEwB,OAAO,CAACxB,EAAE;UACdL,eAAe,EAAE,IAAAmC,2CAA0B,EAACzD,oBAAoB,EAAEmD,OAAO,CAACO,IAAI,CAAC,CAAC;QACpF,CAAC;QACD,IAAMC,GAAG,GAAG;UACRT,SAAS,EAAEA,SAAS;UACpBD,UAAU,EAAEO;QAChB,CAAC;QACD,OAAOG,GAAG;MACd,CAAC;MACD1C,SAAS,EAAE,IAAAwB,qBAAc,EAAChD,OAAO,CAACV,IAAI,CAAC,CAACkC,SAAS;MACjD2C,QAAQ,EAAE,IAAAnB,qBAAc,EAAChD,OAAO,CAACV,IAAI,CAAC,CAAC6E,QAAQ;MAC/CC,OAAO,EAAEjE,WAAW,CAACkE,YAAY,CAAC;IACtC,CAAC;EACL;EAEA,IAAIC,yBAAwE;EAC5E,IAAItE,OAAO,CAACT,IAAI,EAAE;IACd,IAAMgF,UAAU,GAAGvE,OAAO,CAACT,IAAI,EAAE0B,MAAM;IACvCqD,yBAAyB,GAAG;MACxB,MAAMhD,OAAOA,CACTkD,IAAgD,EAClD;QACE,IAAID,UAAU,KAAKrD,SAAS,EAAE;UAC1BsD,IAAI,GAAG,MAAM,IAAAC,kBAAW,EAACD,IAAI,EAAGX,GAAG,IAAKU,UAAU,CAACV,GAAG,CAACa,gBAAgB,CAAC,CAAC;QAC7E;QAEA,IAAMC,aAA6D,GAAG,CAAC,CAAC;QACxE,IAAMC,MAAgB,GAAGJ,IAAI,CAACZ,GAAG,CAACC,GAAG,IAAI;UACrC,IAAMgB,KAAK,GAAIhB,GAAG,CAACa,gBAAgB,CAASlE,WAAW,CAAC;UACxDmE,aAAa,CAACE,KAAK,CAAC,GAAGhB,GAAG;UAC1B,OAAOgB,KAAK;QAChB,CAAC,CAAC;QACF,MAAM,IAAAxC,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;QACtD,IAAIwC,SAAmC,GAAG,EAAE;;QAE5C;AAChB;AACA;AACA;AACA;AACA;QACgB,MAAM,IAAAvC,yBAAc,EAACvC,OAAO,CAACb,SAAS,CAACmD,QAAQ,EAAE,MAAOE,GAAG,IAAK;UAC5DsC,SAAS,GAAG,EAAE,CAAC,CAAC;UAChB;AACpB;AACA;;UAEoB,IAAMC,QAAQ,GAAIC,GAAa,IAAK;YAChC,OAAO,IAAAnC,kBAAO,EACV,IAAAxB,gBAAK,EACDrB,OAAO,CAACb,SAAS,CAACE,UAAU,EAC5B,IAAAyC,gBAAK,EAAC,IAAAG,qBAAU,EAAC,CAAC,EAAE,IAAI,EAAE+C,GAAG,CACjC,CACJ,CAAC;UACL,CAAC;UAED,IAAMC,cAAc,GAAG,MAAM,IAAAC,gCAAe,EAAYN,MAAM,EAAEG,QAAQ,CAAC;UAEzE,IAAMI,YAA6B,GAAG,CAAC,CAAC;UACxCF,cAAc,CAAC3G,OAAO,CAACuF,GAAG,IAAI;YAC1B,IAAMuB,WAAW,GAAG,IAAAC,0CAAyB,EAAC9E,oBAAoB,EAAEsD,GAAG,CAACI,IAAI,CAAC,CAAC,CAAC;YAC/E,IAAMY,KAAK,GAAGhB,GAAG,CAAC3B,EAAE;YACnBkD,WAAW,CAAS5E,WAAW,CAAC,GAAGqE,KAAK;YACzCM,YAAY,CAACN,KAAK,CAAC,GAAGO,WAAW;UACrC,CAAC,CAAC;;UAEF;AACpB;AACA;UACoB,IAAME,KAAK,GAAG,IAAAC,qBAAU,EAACvF,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;UACpD,IAAIkD,QAAQ,GAAG,KAAK;UACpB,MAAM7C,OAAO,CAACC,GAAG,CACbxE,MAAM,CAACqH,OAAO,CAACd,aAAa,CAAC,CAACf,GAAG,CAAC,OAAO,CAACiB,KAAK,EAAEa,QAAQ,CAAC,KAAK;YAC3D,IAAMC,OAA8B,GAAGR,YAAY,CAACN,KAAK,CAAC;YAE1D,IACIc,OAAO,KAEH,CAACD,QAAQ,CAACE,kBAAkB,IAC5BvG,UAAU,CAACwG,eAAe,CAACC,OAAO,CAACH,OAAO,EAASD,QAAQ,CAACE,kBAAkB,EAAE,4BAA4B,CAAC,KAAK,KAAK,CAC1H,EACH;cACE;cACAd,SAAS,CAACvF,IAAI,CAACoG,OAAc,CAAC;YAClC,CAAC,MAAM;cACH;cACAH,QAAQ,GAAG,IAAI;cACf,IAAMO,MAAM,GAAG,IAAAC,cAAG,EAAChG,OAAO,CAACb,SAAS,CAACE,UAAU,EAAEwF,KAAK,CAAC;cACvD,IAAMoB,YAAY,GAAG,IAAAC,gBAAS,EAACR,QAAQ,CAAChB,gBAAgB,CAAC;cACxDuB,YAAY,CAAS1F,oBAAoB,CAAC,GAAG,IAAAsB,0BAAe,EAAC,CAAC;cAC/D,IAAI,CAAC8D,OAAO,EAAE;gBACV;gBACAL,KAAK,CAACa,GAAG,CAACJ,MAAM,EAAE,IAAAK,gCAAe,EAAC5F,WAAW,EAAEyF,YAAY,CAAC,CAAC;cACjE,CAAC,MAAM;gBACH;gBACAX,KAAK,CAACe,MAAM,CAACN,MAAM,EAAE,IAAAK,gCAAe,EAAC5F,WAAW,EAAEyF,YAAY,CAAC,CAAC;cACpE;YACJ;UACJ,CAAC,CACL,CAAC;UAED,IAAIT,QAAQ,EAAE;YACV,MAAMF,KAAK,CAACgB,MAAM,CAAC,CAAC;UACxB;QACJ,CAAC,CAAC;QACF,MAAM,IAAAjE,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;QACtD,OAAOwC,SAAS;MACpB,CAAC;MACDtD,SAAS,EAAExB,OAAO,CAACT,IAAI,CAACiC,SAAS;MACjC2C,QAAQ,EAAEnE,OAAO,CAACT,IAAI,CAAC4E;IAC3B,CAAC;EACL;EAGA,IAAMoC,gBAAgB,GAAG,IAAItH,2BAA2B,CACpDe,OAAO,CAACb,SAAS,EACjBa,OAAO,CAACwG,qBAAqB,EAC7BnH,UAAU,EACVgB,yBAAyB,EACzBiE,yBAAyB,EACzBtE,OAAO,CAACR,IAAI,EACZQ,OAAO,CAACP,SAAS,EACjBO,OAAO,CAACN,SACZ,CAAC;;EAED;AACJ;AACA;EACI,IAAIM,OAAO,CAACR,IAAI,IAAIQ,OAAO,CAACV,IAAI,EAAE;IAC9B,IAAMmH,WAAW,GAAGF,gBAAgB,CAACG,KAAK,CAACC,IAAI,CAACJ,gBAAgB,CAAC;IACjE,IAAMK,YAAY,GAAGL,gBAAgB,CAACM,MAAM,CAACF,IAAI,CAACJ,gBAAgB,CAAC;IACnEA,gBAAgB,CAACG,KAAK,GAAG,MAAM;MAC3B,IAAMI,eAAe,GAAG,IAAAzF,gBAAK,EACzBD,SAAS,EACT,IAAAW,kBAAO,EAACxB,oBAAoB,EAAE,MAAM,CAAC,EACrC,IAAAyB,gBAAK,EAAC,CAAC,CACX,CAAC;MACD,IAAM+E,WAAW,GAAG,IAAAC,qBAAU,EAC1BF,eAAe,EACdG,cAAc,IAAK;QAChB;AACpB;AACA;AACA;AACA;QACoBV,gBAAgB,CAACW,MAAM,CAAC,CAAC;MAC7B,CAAC,EACAC,KAAK,IAAK;QACPZ,gBAAgB,CAACa,QAAQ,CAACD,KAAK,CAACE,IAAI,CAChC,IAAAvG,kBAAU,EAAC,WAAW,EAAE;UAAEqG,KAAK,EAAE,IAAAG,uBAAgB,EAACH,KAAK;QAAE,CAAC,CAC9D,CAAC;MACL,CACJ,CAAC;MACDZ,gBAAgB,CAACM,MAAM,GAAG,MAAM;QAC5BE,WAAW,CAAC,CAAC;QACb,OAAOH,YAAY,CAAC,CAAC;MACzB,CAAC;MACD,OAAOH,WAAW,CAAC,CAAC;IACxB,CAAC;EACL;EAEA,IAAAc,oCAA4B,EAACvH,OAAO,CAACM,iBAAiB,EAAEiG,gBAAgB,CAAC;EAEzE,OAAOA,gBAAgB;AAC3B","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"index.js","names":["_index","require","_firestore","_index2","_index3","_index4","_rxjs","_firestoreHelper","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_firestoreTypes","RxFirestoreReplicationState","_RxReplicationState","firestore","replicationIdentifierHash","collection","pull","push","live","retryTime","autoStart","_this","_inheritsLoose2","default","RxReplicationState","replicateFirestore","options","addRxPlugin","RxDBLeaderElectionPlugin","pullStream$","Subject","replicationPrimitivesPull","waitForLeadership","serverTimestampField","primaryPath","schema","schemaPart","getSchemaByObjectPath","jsonSchema","includes","newRxError","field","pullFilters","filter","undefined","toArray","pullQuery","query","handler","lastPulledCheckpoint","batchSize","newerQuery","sameTimeQuery","lastServerTimestamp","isoStringToServerTimestamp","serverTimestamp","where","orderBy","limit","documentId","id","mustsReRun","useDocs","waitForPendingWrites","database","runTransaction","_tx","newerQueryResult","sameTimeQueryResult","Promise","all","getDocs","metadata","hasPendingWrites","ensureNotFalsy","docs","missingAmount","length","additionalDocs","slice","x","appendToArray","checkpoint","documents","lastDoc","lastOfArray","map","row","firestoreRowToDocData","newCheckpoint","serverTimestampToIsoString","data","ret","modifier","stream$","asObservable","initialCheckpoint","replicationPrimitivesPush","pushFilter","rows","asyncFilter","newDocumentState","writeRowsById","docIds","docId","conflicts","getQuery","ids","docsInDbResult","getContentByIds","docsInDbById","docDataInDb","stripServerTimestampField","batch","writeBatch","hasWrite","entries","writeRow","docInDb","assumedMasterState","conflictHandler","isEqual","docRef","doc","writeDocData","flatClone","set","stripPrimaryKey","update","commit","replicationState","replicationIdentifier","startBefore","start","bind","cancelBefore","cancel","lastChangeQuery","unsubscribe","onSnapshot","_querySnapshot","reSync","error","subjects","next","errorToPlainJson","startReplicationOnLeaderShip"],"sources":["../../../../src/plugins/replication-firestore/index.ts"],"sourcesContent":["import {\n appendToArray,\n asyncFilter,\n ensureNotFalsy,\n errorToPlainJson,\n flatClone,\n lastOfArray,\n toArray\n} from '../../plugins/utils/index.ts';\n\nimport {\n doc,\n query,\n where,\n orderBy,\n limit,\n getDocs,\n onSnapshot,\n runTransaction,\n writeBatch,\n serverTimestamp,\n QueryDocumentSnapshot,\n waitForPendingWrites,\n documentId\n} from 'firebase/firestore';\n\nimport { RxDBLeaderElectionPlugin } from '../leader-election/index.ts';\nimport type {\n RxCollection,\n ReplicationPullOptions,\n ReplicationPushOptions,\n RxReplicationWriteToMasterRow,\n RxReplicationPullStreamItem\n} from '../../types/index.d.ts';\nimport {\n RxReplicationState,\n startReplicationOnLeaderShip\n} from '../replication/index.ts';\nimport {\n addRxPlugin,\n ById,\n getSchemaByObjectPath,\n newRxError,\n WithDeleted\n} from '../../index.ts';\n\nimport type {\n FirestoreCheckpointType,\n FirestoreOptions,\n SyncOptionsFirestore\n} from './firestore-types.ts';\nimport { Subject } from 'rxjs';\nimport {\n firestoreRowToDocData,\n getContentByIds,\n isoStringToServerTimestamp,\n serverTimestampToIsoString,\n stripPrimaryKey,\n stripServerTimestampField\n} from './firestore-helper.ts';\n\nexport * from './firestore-helper.ts';\nexport * from './firestore-types.ts';\n\nexport class RxFirestoreReplicationState extends RxReplicationState {\n constructor(\n public readonly firestore: FirestoreOptions,\n public readonly replicationIdentifierHash: string,\n public readonly collection: RxCollection,\n public readonly pull?: ReplicationPullOptions,\n public readonly push?: ReplicationPushOptions,\n public readonly live: boolean = true,\n public retryTime: number = 1000 * 5,\n public autoStart: boolean = true\n ) {\n super(\n replicationIdentifierHash,\n collection,\n '_deleted',\n pull,\n push,\n live,\n retryTime,\n autoStart\n );\n }\n}\n\nexport function replicateFirestore(\n options: SyncOptionsFirestore\n): RxFirestoreReplicationState {\n const collection: RxCollection = options.collection;\n addRxPlugin(RxDBLeaderElectionPlugin);\n const pullStream$: Subject> = new Subject();\n let replicationPrimitivesPull: ReplicationPullOptions | undefined;\n options.live = typeof options.live === 'undefined' ? true : options.live;\n options.waitForLeadership = typeof options.waitForLeadership === 'undefined' ? true : options.waitForLeadership;\n const serverTimestampField = typeof options.serverTimestampField === 'undefined' ? 'serverTimestamp' : options.serverTimestampField;\n options.serverTimestampField = serverTimestampField;\n const primaryPath = collection.schema.primaryPath;\n\n /**\n * The serverTimestampField MUST NOT be part of the collections RxJsonSchema.\n */\n const schemaPart = getSchemaByObjectPath(collection.schema.jsonSchema, serverTimestampField);\n if (\n schemaPart ||\n // also must not be nested.\n serverTimestampField.includes('.')\n ) {\n throw newRxError('RC6', {\n field: serverTimestampField,\n schema: collection.schema.jsonSchema\n });\n }\n\n const pullFilters = options.pull?.filter !== undefined\n ? toArray(options.pull.filter)\n : [];\n\n const pullQuery = query(options.firestore.collection, ...pullFilters);\n\n if (options.pull) {\n replicationPrimitivesPull = {\n async handler(\n lastPulledCheckpoint: FirestoreCheckpointType | undefined,\n batchSize: number\n ) {\n let newerQuery: ReturnType;\n let sameTimeQuery: ReturnType | undefined;\n\n if (lastPulledCheckpoint) {\n const lastServerTimestamp = isoStringToServerTimestamp(lastPulledCheckpoint.serverTimestamp);\n newerQuery = query(pullQuery,\n where(serverTimestampField, '>', lastServerTimestamp),\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n sameTimeQuery = query(pullQuery,\n where(serverTimestampField, '==', lastServerTimestamp),\n where(documentId(), '>', lastPulledCheckpoint.id),\n orderBy(documentId(), 'asc'),\n limit(batchSize)\n );\n } else {\n newerQuery = query(pullQuery,\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n }\n\n let mustsReRun = true;\n let useDocs: QueryDocumentSnapshot[] = [];\n while (mustsReRun) {\n /**\n * Local writes that have not been persisted to the server\n * are in pending state and do not have a correct serverTimestamp set.\n * We have to ensure we only use document states that are in sync with the server.\n * @link https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b\n */\n await waitForPendingWrites(options.firestore.database);\n await runTransaction(options.firestore.database, async (_tx) => {\n useDocs = [];\n const [\n newerQueryResult,\n sameTimeQueryResult\n ] = await Promise.all([\n getDocs(newerQuery),\n sameTimeQuery ? getDocs(sameTimeQuery) : undefined\n ]);\n\n if (\n newerQueryResult.metadata.hasPendingWrites ||\n (sameTimeQuery && ensureNotFalsy(sameTimeQueryResult).metadata.hasPendingWrites)\n ) {\n return;\n } else {\n mustsReRun = false;\n\n if (sameTimeQuery) {\n useDocs = ensureNotFalsy(sameTimeQueryResult).docs as any;\n }\n const missingAmount = batchSize - useDocs.length;\n if (missingAmount > 0) {\n const additionalDocs = newerQueryResult.docs.slice(0, missingAmount).filter(x => !!x);\n appendToArray(useDocs, additionalDocs);\n }\n }\n });\n }\n\n if (useDocs.length === 0) {\n return {\n checkpoint: lastPulledCheckpoint ?? null,\n documents: []\n };\n }\n const lastDoc = ensureNotFalsy(lastOfArray(useDocs));\n const documents: WithDeleted[] = useDocs\n .map(row => firestoreRowToDocData(\n serverTimestampField,\n primaryPath,\n row\n ));\n const newCheckpoint: FirestoreCheckpointType = {\n id: lastDoc.id,\n serverTimestamp: serverTimestampToIsoString(serverTimestampField, lastDoc.data())\n };\n const ret = {\n documents: documents,\n checkpoint: newCheckpoint\n };\n return ret;\n },\n batchSize: ensureNotFalsy(options.pull).batchSize,\n modifier: ensureNotFalsy(options.pull).modifier,\n stream$: pullStream$.asObservable(),\n initialCheckpoint: options.pull.initialCheckpoint\n };\n }\n\n let replicationPrimitivesPush: ReplicationPushOptions | undefined;\n if (options.push) {\n const pushFilter = options.push?.filter;\n replicationPrimitivesPush = {\n async handler(\n rows: RxReplicationWriteToMasterRow[]\n ) {\n if (pushFilter !== undefined) {\n rows = await asyncFilter(rows, (row) => pushFilter(row.newDocumentState));\n }\n\n const writeRowsById: ById> = {};\n const docIds: string[] = rows.map(row => {\n const docId = (row.newDocumentState as any)[primaryPath];\n writeRowsById[docId] = row;\n return docId;\n });\n await waitForPendingWrites(options.firestore.database);\n let conflicts: WithDeleted[] = [];\n\n /**\n * Everything must run INSIDE of the transaction\n * because on tx-errors, firebase will re-run the transaction on some cases.\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#transaction_failure\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions\n */\n await runTransaction(options.firestore.database, async (_tx) => {\n conflicts = []; // reset in case the tx has re-run.\n /**\n * @link https://stackoverflow.com/a/48423626/3443137\n */\n\n const getQuery = (ids: string[]) => {\n return getDocs(\n query(\n options.firestore.collection,\n where(documentId(), 'in', ids)\n )\n );\n };\n\n const docsInDbResult = await getContentByIds(docIds, getQuery);\n\n const docsInDbById: ById = {};\n docsInDbResult.forEach(row => {\n const docDataInDb = stripServerTimestampField(serverTimestampField, row.data());\n const docId = row.id;\n (docDataInDb as any)[primaryPath] = docId;\n docsInDbById[docId] = docDataInDb;\n });\n\n /**\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n */\n const batch = writeBatch(options.firestore.database);\n let hasWrite = false;\n await Promise.all(\n Object.entries(writeRowsById).map(async ([docId, writeRow]) => {\n const docInDb: RxDocType | undefined = docsInDbById[docId];\n\n if (\n docInDb &&\n (\n !writeRow.assumedMasterState ||\n collection.conflictHandler.isEqual(docInDb as any, writeRow.assumedMasterState, 'replication-firestore-push') === false\n )\n ) {\n // conflict\n conflicts.push(docInDb as any);\n } else {\n // no conflict\n hasWrite = true;\n const docRef = doc(options.firestore.collection, docId);\n const writeDocData = flatClone(writeRow.newDocumentState);\n (writeDocData as any)[serverTimestampField] = serverTimestamp();\n if (!docInDb) {\n // insert\n batch.set(docRef, stripPrimaryKey(primaryPath, writeDocData));\n } else {\n // update\n batch.update(docRef, stripPrimaryKey(primaryPath, writeDocData));\n }\n }\n })\n );\n\n if (hasWrite) {\n await batch.commit();\n }\n });\n await waitForPendingWrites(options.firestore.database);\n return conflicts;\n },\n batchSize: options.push.batchSize,\n modifier: options.push.modifier\n };\n }\n\n\n const replicationState = new RxFirestoreReplicationState(\n options.firestore,\n options.replicationIdentifier,\n collection,\n replicationPrimitivesPull,\n replicationPrimitivesPush,\n options.live,\n options.retryTime,\n options.autoStart\n );\n\n /**\n * Use long polling to get live changes for the pull.stream$\n */\n if (options.live && options.pull) {\n const startBefore = replicationState.start.bind(replicationState);\n const cancelBefore = replicationState.cancel.bind(replicationState);\n replicationState.start = () => {\n const lastChangeQuery = query(\n pullQuery,\n orderBy(serverTimestampField, 'desc'),\n limit(1)\n );\n const unsubscribe = onSnapshot(\n lastChangeQuery,\n (_querySnapshot) => {\n /**\n * There is no good way to observe the event stream in firestore.\n * So instead we listen to any write to the collection\n * and then emit a 'RESYNC' flag.\n */\n replicationState.reSync();\n },\n (error) => {\n replicationState.subjects.error.next(\n newRxError('RC_STREAM', { error: errorToPlainJson(error) })\n );\n }\n );\n replicationState.cancel = () => {\n unsubscribe();\n return cancelBefore();\n };\n return startBefore();\n };\n }\n\n startReplicationOnLeaderShip(options.waitForLeadership, replicationState);\n\n return replicationState;\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAUA,IAAAC,UAAA,GAAAD,OAAA;AAgBA,IAAAE,OAAA,GAAAF,OAAA;AAQA,IAAAG,OAAA,GAAAH,OAAA;AAIA,IAAAI,OAAA,GAAAJ,OAAA;AAaA,IAAAK,KAAA,GAAAL,OAAA;AACA,IAAAM,gBAAA,GAAAN,OAAA;AASAO,MAAA,CAAAC,IAAA,CAAAF,gBAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,gBAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,gBAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AACA,IAAAS,eAAA,GAAAnB,OAAA;AAAAO,MAAA,CAAAC,IAAA,CAAAW,eAAA,EAAAV,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAS,eAAA,CAAAT,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,eAAA,CAAAT,GAAA;IAAA;EAAA;AAAA;AAAqC,IAExBU,2BAA2B,GAAAL,OAAA,CAAAK,2BAAA,0BAAAC,mBAAA;EACpC,SAAAD,4BACoBE,SAAsC,EACtCC,yBAAiC,EACjCC,UAAmC,EACnCC,IAAiE,EACjEC,IAAwC,EACxCC,IAAa,GAAG,IAAI,EAC7BC,SAAiB,GAAG,IAAI,GAAG,CAAC,EAC5BC,SAAkB,GAAG,IAAI,EAClC;IAAA,IAAAC,KAAA;IACEA,KAAA,GAAAT,mBAAA,CAAAR,IAAA,OACIU,yBAAyB,EACzBC,UAAU,EACV,UAAU,EACVC,IAAI,EACJC,IAAI,EACJC,IAAI,EACJC,SAAS,EACTC,SACJ,CAAC;IAACC,KAAA,CAlBcR,SAAsC,GAAtCA,SAAsC;IAAAQ,KAAA,CACtCP,yBAAiC,GAAjCA,yBAAiC;IAAAO,KAAA,CACjCN,UAAmC,GAAnCA,UAAmC;IAAAM,KAAA,CACnCL,IAAiE,GAAjEA,IAAiE;IAAAK,KAAA,CACjEJ,IAAwC,GAAxCA,IAAwC;IAAAI,KAAA,CACxCH,IAAa,GAAbA,IAAa;IAAAG,KAAA,CACtBF,SAAiB,GAAjBA,SAAiB;IAAAE,KAAA,CACjBD,SAAkB,GAAlBA,SAAkB;IAAA,OAAAC,KAAA;EAY7B;EAAC,IAAAC,eAAA,CAAAC,OAAA,EAAAZ,2BAAA,EAAAC,mBAAA;EAAA,OAAAD,2BAAA;AAAA,EArBuDa,0BAAkB;AAwBvE,SAASC,kBAAkBA,CAC9BC,OAAwC,EACF;EACtC,IAAMX,UAAmC,GAAGW,OAAO,CAACX,UAAU;EAC9D,IAAAY,mBAAW,EAACC,gCAAwB,CAAC;EACrC,IAAMC,WAAqF,GAAG,IAAIC,aAAO,CAAC,CAAC;EAC3G,IAAIC,yBAAiG;EACrGL,OAAO,CAACR,IAAI,GAAG,OAAOQ,OAAO,CAACR,IAAI,KAAK,WAAW,GAAG,IAAI,GAAGQ,OAAO,CAACR,IAAI;EACxEQ,OAAO,CAACM,iBAAiB,GAAG,OAAON,OAAO,CAACM,iBAAiB,KAAK,WAAW,GAAG,IAAI,GAAGN,OAAO,CAACM,iBAAiB;EAC/G,IAAMC,oBAAoB,GAAG,OAAOP,OAAO,CAACO,oBAAoB,KAAK,WAAW,GAAG,iBAAiB,GAAGP,OAAO,CAACO,oBAAoB;EACnIP,OAAO,CAACO,oBAAoB,GAAGA,oBAAoB;EACnD,IAAMC,WAAW,GAAGnB,UAAU,CAACoB,MAAM,CAACD,WAAW;;EAEjD;AACJ;AACA;EACI,IAAME,UAAU,GAAG,IAAAC,6BAAqB,EAACtB,UAAU,CAACoB,MAAM,CAACG,UAAU,EAAEL,oBAAoB,CAAC;EAC5F,IACIG,UAAU;EACV;EACAH,oBAAoB,CAACM,QAAQ,CAAC,GAAG,CAAC,EACpC;IACE,MAAM,IAAAC,kBAAU,EAAC,KAAK,EAAE;MACpBC,KAAK,EAAER,oBAAoB;MAC3BE,MAAM,EAAEpB,UAAU,CAACoB,MAAM,CAACG;IAC9B,CAAC,CAAC;EACN;EAEA,IAAMI,WAAW,GAAGhB,OAAO,CAACV,IAAI,EAAE2B,MAAM,KAAKC,SAAS,GAChD,IAAAC,cAAO,EAACnB,OAAO,CAACV,IAAI,CAAC2B,MAAM,CAAC,GAC5B,EAAE;EAER,IAAMG,SAAS,GAAG,IAAAC,gBAAK,EAACrB,OAAO,CAACb,SAAS,CAACE,UAAU,EAAE,GAAG2B,WAAW,CAAC;EAErE,IAAIhB,OAAO,CAACV,IAAI,EAAE;IACde,yBAAyB,GAAG;MACxB,MAAMiB,OAAOA,CACTC,oBAAyD,EACzDC,SAAiB,EACnB;QACE,IAAIC,UAAoC;QACxC,IAAIC,aAAmD;QAEvD,IAAIH,oBAAoB,EAAE;UACtB,IAAMI,mBAAmB,GAAG,IAAAC,2CAA0B,EAACL,oBAAoB,CAACM,eAAe,CAAC;UAC5FJ,UAAU,GAAG,IAAAJ,gBAAK,EAACD,SAAS,EACxB,IAAAU,gBAAK,EAACvB,oBAAoB,EAAE,GAAG,EAAEoB,mBAAmB,CAAC,EACrD,IAAAI,kBAAO,EAACxB,oBAAoB,EAAE,KAAK,CAAC,EACpC,IAAAyB,gBAAK,EAACR,SAAS,CACnB,CAAC;UACDE,aAAa,GAAG,IAAAL,gBAAK,EAACD,SAAS,EAC3B,IAAAU,gBAAK,EAACvB,oBAAoB,EAAE,IAAI,EAAEoB,mBAAmB,CAAC,EACtD,IAAAG,gBAAK,EAAC,IAAAG,qBAAU,EAAC,CAAC,EAAE,GAAG,EAAEV,oBAAoB,CAACW,EAAE,CAAC,EACjD,IAAAH,kBAAO,EAAC,IAAAE,qBAAU,EAAC,CAAC,EAAE,KAAK,CAAC,EAC5B,IAAAD,gBAAK,EAACR,SAAS,CACnB,CAAC;QACL,CAAC,MAAM;UACHC,UAAU,GAAG,IAAAJ,gBAAK,EAACD,SAAS,EACxB,IAAAW,kBAAO,EAACxB,oBAAoB,EAAE,KAAK,CAAC,EACpC,IAAAyB,gBAAK,EAACR,SAAS,CACnB,CAAC;QACL;QAEA,IAAIW,UAAU,GAAG,IAAI;QACrB,IAAIC,OAA2C,GAAG,EAAE;QACpD,OAAOD,UAAU,EAAE;UACf;AACpB;AACA;AACA;AACA;AACA;UACoB,MAAM,IAAAE,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;UACtD,MAAM,IAAAC,yBAAc,EAACvC,OAAO,CAACb,SAAS,CAACmD,QAAQ,EAAE,MAAOE,GAAG,IAAK;YAC5DJ,OAAO,GAAG,EAAE;YACZ,IAAM,CACFK,gBAAgB,EAChBC,mBAAmB,CACtB,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAClB,IAAAC,kBAAO,EAACpB,UAAU,CAAC,EACnBC,aAAa,GAAG,IAAAmB,kBAAO,EAACnB,aAAa,CAAC,GAAGR,SAAS,CACrD,CAAC;YAEF,IACIuB,gBAAgB,CAACK,QAAQ,CAACC,gBAAgB,IACzCrB,aAAa,IAAI,IAAAsB,qBAAc,EAACN,mBAAmB,CAAC,CAACI,QAAQ,CAACC,gBAAiB,EAClF;cACE;YACJ,CAAC,MAAM;cACHZ,UAAU,GAAG,KAAK;cAElB,IAAIT,aAAa,EAAE;gBACfU,OAAO,GAAG,IAAAY,qBAAc,EAACN,mBAAmB,CAAC,CAACO,IAAW;cAC7D;cACA,IAAMC,aAAa,GAAG1B,SAAS,GAAGY,OAAO,CAACe,MAAM;cAChD,IAAID,aAAa,GAAG,CAAC,EAAE;gBACnB,IAAME,cAAc,GAAGX,gBAAgB,CAACQ,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEH,aAAa,CAAC,CAACjC,MAAM,CAACqC,CAAC,IAAI,CAAC,CAACA,CAAC,CAAC;gBACrF,IAAAC,oBAAa,EAACnB,OAAO,EAAEgB,cAAc,CAAC;cAC1C;YACJ;UACJ,CAAC,CAAC;QACN;QAEA,IAAIhB,OAAO,CAACe,MAAM,KAAK,CAAC,EAAE;UACtB,OAAO;YACHK,UAAU,EAAEjC,oBAAoB,IAAI,IAAI;YACxCkC,SAAS,EAAE;UACf,CAAC;QACL;QACA,IAAMC,OAAO,GAAG,IAAAV,qBAAc,EAAC,IAAAW,kBAAW,EAACvB,OAAO,CAAC,CAAC;QACpD,IAAMqB,SAAmC,GAAGrB,OAAO,CAC9CwB,GAAG,CAACC,GAAG,IAAI,IAAAC,sCAAqB,EAC7BvD,oBAAoB,EACpBC,WAAW,EACXqD,GACJ,CAAC,CAAC;QACN,IAAME,aAAsC,GAAG;UAC3C7B,EAAE,EAAEwB,OAAO,CAACxB,EAAE;UACdL,eAAe,EAAE,IAAAmC,2CAA0B,EAACzD,oBAAoB,EAAEmD,OAAO,CAACO,IAAI,CAAC,CAAC;QACpF,CAAC;QACD,IAAMC,GAAG,GAAG;UACRT,SAAS,EAAEA,SAAS;UACpBD,UAAU,EAAEO;QAChB,CAAC;QACD,OAAOG,GAAG;MACd,CAAC;MACD1C,SAAS,EAAE,IAAAwB,qBAAc,EAAChD,OAAO,CAACV,IAAI,CAAC,CAACkC,SAAS;MACjD2C,QAAQ,EAAE,IAAAnB,qBAAc,EAAChD,OAAO,CAACV,IAAI,CAAC,CAAC6E,QAAQ;MAC/CC,OAAO,EAAEjE,WAAW,CAACkE,YAAY,CAAC,CAAC;MACnCC,iBAAiB,EAAEtE,OAAO,CAACV,IAAI,CAACgF;IACpC,CAAC;EACL;EAEA,IAAIC,yBAAwE;EAC5E,IAAIvE,OAAO,CAACT,IAAI,EAAE;IACd,IAAMiF,UAAU,GAAGxE,OAAO,CAACT,IAAI,EAAE0B,MAAM;IACvCsD,yBAAyB,GAAG;MACxB,MAAMjD,OAAOA,CACTmD,IAAgD,EAClD;QACE,IAAID,UAAU,KAAKtD,SAAS,EAAE;UAC1BuD,IAAI,GAAG,MAAM,IAAAC,kBAAW,EAACD,IAAI,EAAGZ,GAAG,IAAKW,UAAU,CAACX,GAAG,CAACc,gBAAgB,CAAC,CAAC;QAC7E;QAEA,IAAMC,aAA6D,GAAG,CAAC,CAAC;QACxE,IAAMC,MAAgB,GAAGJ,IAAI,CAACb,GAAG,CAACC,GAAG,IAAI;UACrC,IAAMiB,KAAK,GAAIjB,GAAG,CAACc,gBAAgB,CAASnE,WAAW,CAAC;UACxDoE,aAAa,CAACE,KAAK,CAAC,GAAGjB,GAAG;UAC1B,OAAOiB,KAAK;QAChB,CAAC,CAAC;QACF,MAAM,IAAAzC,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;QACtD,IAAIyC,SAAmC,GAAG,EAAE;;QAE5C;AAChB;AACA;AACA;AACA;AACA;QACgB,MAAM,IAAAxC,yBAAc,EAACvC,OAAO,CAACb,SAAS,CAACmD,QAAQ,EAAE,MAAOE,GAAG,IAAK;UAC5DuC,SAAS,GAAG,EAAE,CAAC,CAAC;UAChB;AACpB;AACA;;UAEoB,IAAMC,QAAQ,GAAIC,GAAa,IAAK;YAChC,OAAO,IAAApC,kBAAO,EACV,IAAAxB,gBAAK,EACDrB,OAAO,CAACb,SAAS,CAACE,UAAU,EAC5B,IAAAyC,gBAAK,EAAC,IAAAG,qBAAU,EAAC,CAAC,EAAE,IAAI,EAAEgD,GAAG,CACjC,CACJ,CAAC;UACL,CAAC;UAED,IAAMC,cAAc,GAAG,MAAM,IAAAC,gCAAe,EAAYN,MAAM,EAAEG,QAAQ,CAAC;UAEzE,IAAMI,YAA6B,GAAG,CAAC,CAAC;UACxCF,cAAc,CAAC5G,OAAO,CAACuF,GAAG,IAAI;YAC1B,IAAMwB,WAAW,GAAG,IAAAC,0CAAyB,EAAC/E,oBAAoB,EAAEsD,GAAG,CAACI,IAAI,CAAC,CAAC,CAAC;YAC/E,IAAMa,KAAK,GAAGjB,GAAG,CAAC3B,EAAE;YACnBmD,WAAW,CAAS7E,WAAW,CAAC,GAAGsE,KAAK;YACzCM,YAAY,CAACN,KAAK,CAAC,GAAGO,WAAW;UACrC,CAAC,CAAC;;UAEF;AACpB;AACA;UACoB,IAAME,KAAK,GAAG,IAAAC,qBAAU,EAACxF,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;UACpD,IAAImD,QAAQ,GAAG,KAAK;UACpB,MAAM9C,OAAO,CAACC,GAAG,CACbxE,MAAM,CAACsH,OAAO,CAACd,aAAa,CAAC,CAAChB,GAAG,CAAC,OAAO,CAACkB,KAAK,EAAEa,QAAQ,CAAC,KAAK;YAC3D,IAAMC,OAA8B,GAAGR,YAAY,CAACN,KAAK,CAAC;YAE1D,IACIc,OAAO,KAEH,CAACD,QAAQ,CAACE,kBAAkB,IAC5BxG,UAAU,CAACyG,eAAe,CAACC,OAAO,CAACH,OAAO,EAASD,QAAQ,CAACE,kBAAkB,EAAE,4BAA4B,CAAC,KAAK,KAAK,CAC1H,EACH;cACE;cACAd,SAAS,CAACxF,IAAI,CAACqG,OAAc,CAAC;YAClC,CAAC,MAAM;cACH;cACAH,QAAQ,GAAG,IAAI;cACf,IAAMO,MAAM,GAAG,IAAAC,cAAG,EAACjG,OAAO,CAACb,SAAS,CAACE,UAAU,EAAEyF,KAAK,CAAC;cACvD,IAAMoB,YAAY,GAAG,IAAAC,gBAAS,EAACR,QAAQ,CAAChB,gBAAgB,CAAC;cACxDuB,YAAY,CAAS3F,oBAAoB,CAAC,GAAG,IAAAsB,0BAAe,EAAC,CAAC;cAC/D,IAAI,CAAC+D,OAAO,EAAE;gBACV;gBACAL,KAAK,CAACa,GAAG,CAACJ,MAAM,EAAE,IAAAK,gCAAe,EAAC7F,WAAW,EAAE0F,YAAY,CAAC,CAAC;cACjE,CAAC,MAAM;gBACH;gBACAX,KAAK,CAACe,MAAM,CAACN,MAAM,EAAE,IAAAK,gCAAe,EAAC7F,WAAW,EAAE0F,YAAY,CAAC,CAAC;cACpE;YACJ;UACJ,CAAC,CACL,CAAC;UAED,IAAIT,QAAQ,EAAE;YACV,MAAMF,KAAK,CAACgB,MAAM,CAAC,CAAC;UACxB;QACJ,CAAC,CAAC;QACF,MAAM,IAAAlE,+BAAoB,EAACrC,OAAO,CAACb,SAAS,CAACmD,QAAQ,CAAC;QACtD,OAAOyC,SAAS;MACpB,CAAC;MACDvD,SAAS,EAAExB,OAAO,CAACT,IAAI,CAACiC,SAAS;MACjC2C,QAAQ,EAAEnE,OAAO,CAACT,IAAI,CAAC4E;IAC3B,CAAC;EACL;EAGA,IAAMqC,gBAAgB,GAAG,IAAIvH,2BAA2B,CACpDe,OAAO,CAACb,SAAS,EACjBa,OAAO,CAACyG,qBAAqB,EAC7BpH,UAAU,EACVgB,yBAAyB,EACzBkE,yBAAyB,EACzBvE,OAAO,CAACR,IAAI,EACZQ,OAAO,CAACP,SAAS,EACjBO,OAAO,CAACN,SACZ,CAAC;;EAED;AACJ;AACA;EACI,IAAIM,OAAO,CAACR,IAAI,IAAIQ,OAAO,CAACV,IAAI,EAAE;IAC9B,IAAMoH,WAAW,GAAGF,gBAAgB,CAACG,KAAK,CAACC,IAAI,CAACJ,gBAAgB,CAAC;IACjE,IAAMK,YAAY,GAAGL,gBAAgB,CAACM,MAAM,CAACF,IAAI,CAACJ,gBAAgB,CAAC;IACnEA,gBAAgB,CAACG,KAAK,GAAG,MAAM;MAC3B,IAAMI,eAAe,GAAG,IAAA1F,gBAAK,EACzBD,SAAS,EACT,IAAAW,kBAAO,EAACxB,oBAAoB,EAAE,MAAM,CAAC,EACrC,IAAAyB,gBAAK,EAAC,CAAC,CACX,CAAC;MACD,IAAMgF,WAAW,GAAG,IAAAC,qBAAU,EAC1BF,eAAe,EACdG,cAAc,IAAK;QAChB;AACpB;AACA;AACA;AACA;QACoBV,gBAAgB,CAACW,MAAM,CAAC,CAAC;MAC7B,CAAC,EACAC,KAAK,IAAK;QACPZ,gBAAgB,CAACa,QAAQ,CAACD,KAAK,CAACE,IAAI,CAChC,IAAAxG,kBAAU,EAAC,WAAW,EAAE;UAAEsG,KAAK,EAAE,IAAAG,uBAAgB,EAACH,KAAK;QAAE,CAAC,CAC9D,CAAC;MACL,CACJ,CAAC;MACDZ,gBAAgB,CAACM,MAAM,GAAG,MAAM;QAC5BE,WAAW,CAAC,CAAC;QACb,OAAOH,YAAY,CAAC,CAAC;MACzB,CAAC;MACD,OAAOH,WAAW,CAAC,CAAC;IACxB,CAAC;EACL;EAEA,IAAAc,oCAA4B,EAACxH,OAAO,CAACM,iBAAiB,EAAEkG,gBAAgB,CAAC;EAEzE,OAAOA,gBAAgB;AAC3B","ignoreList":[]} \ No newline at end of file diff --git a/dist/esm/plugins/replication-firestore/index.js b/dist/esm/plugins/replication-firestore/index.js index cb4b317f131..a165a0abb10 100644 --- a/dist/esm/plugins/replication-firestore/index.js +++ b/dist/esm/plugins/replication-firestore/index.js @@ -110,7 +110,8 @@ export function replicateFirestore(options) { }, batchSize: ensureNotFalsy(options.pull).batchSize, modifier: ensureNotFalsy(options.pull).modifier, - stream$: pullStream$.asObservable() + stream$: pullStream$.asObservable(), + initialCheckpoint: options.pull.initialCheckpoint }; } var replicationPrimitivesPush; diff --git a/dist/esm/plugins/replication-firestore/index.js.map b/dist/esm/plugins/replication-firestore/index.js.map index bd8110e6286..cb38db83e4f 100644 --- a/dist/esm/plugins/replication-firestore/index.js.map +++ b/dist/esm/plugins/replication-firestore/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","names":["appendToArray","asyncFilter","ensureNotFalsy","errorToPlainJson","flatClone","lastOfArray","toArray","doc","query","where","orderBy","limit","getDocs","onSnapshot","runTransaction","writeBatch","serverTimestamp","waitForPendingWrites","documentId","RxDBLeaderElectionPlugin","RxReplicationState","startReplicationOnLeaderShip","addRxPlugin","getSchemaByObjectPath","newRxError","Subject","firestoreRowToDocData","getContentByIds","isoStringToServerTimestamp","serverTimestampToIsoString","stripPrimaryKey","stripServerTimestampField","RxFirestoreReplicationState","_RxReplicationState","firestore","replicationIdentifierHash","collection","pull","push","live","retryTime","autoStart","_this","call","_inheritsLoose","replicateFirestore","options","pullStream$","replicationPrimitivesPull","waitForLeadership","serverTimestampField","primaryPath","schema","schemaPart","jsonSchema","includes","field","pullFilters","filter","undefined","pullQuery","handler","lastPulledCheckpoint","batchSize","newerQuery","sameTimeQuery","lastServerTimestamp","id","mustsReRun","useDocs","database","_tx","newerQueryResult","sameTimeQueryResult","Promise","all","metadata","hasPendingWrites","docs","missingAmount","length","additionalDocs","slice","x","checkpoint","documents","lastDoc","map","row","newCheckpoint","data","ret","modifier","stream$","asObservable","replicationPrimitivesPush","pushFilter","rows","newDocumentState","writeRowsById","docIds","docId","conflicts","getQuery","ids","docsInDbResult","docsInDbById","forEach","docDataInDb","batch","hasWrite","Object","entries","writeRow","docInDb","assumedMasterState","conflictHandler","isEqual","docRef","writeDocData","set","update","commit","replicationState","replicationIdentifier","startBefore","start","bind","cancelBefore","cancel","lastChangeQuery","unsubscribe","_querySnapshot","reSync","error","subjects","next"],"sources":["../../../../src/plugins/replication-firestore/index.ts"],"sourcesContent":["import {\n appendToArray,\n asyncFilter,\n ensureNotFalsy,\n errorToPlainJson,\n flatClone,\n lastOfArray,\n toArray\n} from '../../plugins/utils/index.ts';\n\nimport {\n doc,\n query,\n where,\n orderBy,\n limit,\n getDocs,\n onSnapshot,\n runTransaction,\n writeBatch,\n serverTimestamp,\n QueryDocumentSnapshot,\n waitForPendingWrites,\n documentId\n} from 'firebase/firestore';\n\nimport { RxDBLeaderElectionPlugin } from '../leader-election/index.ts';\nimport type {\n RxCollection,\n ReplicationPullOptions,\n ReplicationPushOptions,\n RxReplicationWriteToMasterRow,\n RxReplicationPullStreamItem\n} from '../../types/index.d.ts';\nimport {\n RxReplicationState,\n startReplicationOnLeaderShip\n} from '../replication/index.ts';\nimport {\n addRxPlugin,\n ById,\n getSchemaByObjectPath,\n newRxError,\n WithDeleted\n} from '../../index.ts';\n\nimport type {\n FirestoreCheckpointType,\n FirestoreOptions,\n SyncOptionsFirestore\n} from './firestore-types.ts';\nimport { Subject } from 'rxjs';\nimport {\n firestoreRowToDocData,\n getContentByIds,\n isoStringToServerTimestamp,\n serverTimestampToIsoString,\n stripPrimaryKey,\n stripServerTimestampField\n} from './firestore-helper.ts';\n\nexport * from './firestore-helper.ts';\nexport * from './firestore-types.ts';\n\nexport class RxFirestoreReplicationState extends RxReplicationState {\n constructor(\n public readonly firestore: FirestoreOptions,\n public readonly replicationIdentifierHash: string,\n public readonly collection: RxCollection,\n public readonly pull?: ReplicationPullOptions,\n public readonly push?: ReplicationPushOptions,\n public readonly live: boolean = true,\n public retryTime: number = 1000 * 5,\n public autoStart: boolean = true\n ) {\n super(\n replicationIdentifierHash,\n collection,\n '_deleted',\n pull,\n push,\n live,\n retryTime,\n autoStart\n );\n }\n}\n\nexport function replicateFirestore(\n options: SyncOptionsFirestore\n): RxFirestoreReplicationState {\n const collection: RxCollection = options.collection;\n addRxPlugin(RxDBLeaderElectionPlugin);\n const pullStream$: Subject> = new Subject();\n let replicationPrimitivesPull: ReplicationPullOptions | undefined;\n options.live = typeof options.live === 'undefined' ? true : options.live;\n options.waitForLeadership = typeof options.waitForLeadership === 'undefined' ? true : options.waitForLeadership;\n const serverTimestampField = typeof options.serverTimestampField === 'undefined' ? 'serverTimestamp' : options.serverTimestampField;\n options.serverTimestampField = serverTimestampField;\n const primaryPath = collection.schema.primaryPath;\n\n /**\n * The serverTimestampField MUST NOT be part of the collections RxJsonSchema.\n */\n const schemaPart = getSchemaByObjectPath(collection.schema.jsonSchema, serverTimestampField);\n if (\n schemaPart ||\n // also must not be nested.\n serverTimestampField.includes('.')\n ) {\n throw newRxError('RC6', {\n field: serverTimestampField,\n schema: collection.schema.jsonSchema\n });\n }\n\n const pullFilters = options.pull?.filter !== undefined\n ? toArray(options.pull.filter)\n : [];\n\n const pullQuery = query(options.firestore.collection, ...pullFilters);\n\n if (options.pull) {\n replicationPrimitivesPull = {\n async handler(\n lastPulledCheckpoint: FirestoreCheckpointType | undefined,\n batchSize: number\n ) {\n let newerQuery: ReturnType;\n let sameTimeQuery: ReturnType | undefined;\n\n if (lastPulledCheckpoint) {\n const lastServerTimestamp = isoStringToServerTimestamp(lastPulledCheckpoint.serverTimestamp);\n newerQuery = query(pullQuery,\n where(serverTimestampField, '>', lastServerTimestamp),\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n sameTimeQuery = query(pullQuery,\n where(serverTimestampField, '==', lastServerTimestamp),\n where(documentId(), '>', lastPulledCheckpoint.id),\n orderBy(documentId(), 'asc'),\n limit(batchSize)\n );\n } else {\n newerQuery = query(pullQuery,\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n }\n\n let mustsReRun = true;\n let useDocs: QueryDocumentSnapshot[] = [];\n while (mustsReRun) {\n /**\n * Local writes that have not been persisted to the server\n * are in pending state and do not have a correct serverTimestamp set.\n * We have to ensure we only use document states that are in sync with the server.\n * @link https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b\n */\n await waitForPendingWrites(options.firestore.database);\n await runTransaction(options.firestore.database, async (_tx) => {\n useDocs = [];\n const [\n newerQueryResult,\n sameTimeQueryResult\n ] = await Promise.all([\n getDocs(newerQuery),\n sameTimeQuery ? getDocs(sameTimeQuery) : undefined\n ]);\n\n if (\n newerQueryResult.metadata.hasPendingWrites ||\n (sameTimeQuery && ensureNotFalsy(sameTimeQueryResult).metadata.hasPendingWrites)\n ) {\n return;\n } else {\n mustsReRun = false;\n\n if (sameTimeQuery) {\n useDocs = ensureNotFalsy(sameTimeQueryResult).docs as any;\n }\n const missingAmount = batchSize - useDocs.length;\n if (missingAmount > 0) {\n const additionalDocs = newerQueryResult.docs.slice(0, missingAmount).filter(x => !!x);\n appendToArray(useDocs, additionalDocs);\n }\n }\n });\n }\n\n if (useDocs.length === 0) {\n return {\n checkpoint: lastPulledCheckpoint ?? null,\n documents: []\n };\n }\n const lastDoc = ensureNotFalsy(lastOfArray(useDocs));\n const documents: WithDeleted[] = useDocs\n .map(row => firestoreRowToDocData(\n serverTimestampField,\n primaryPath,\n row\n ));\n const newCheckpoint: FirestoreCheckpointType = {\n id: lastDoc.id,\n serverTimestamp: serverTimestampToIsoString(serverTimestampField, lastDoc.data())\n };\n const ret = {\n documents: documents,\n checkpoint: newCheckpoint\n };\n return ret;\n },\n batchSize: ensureNotFalsy(options.pull).batchSize,\n modifier: ensureNotFalsy(options.pull).modifier,\n stream$: pullStream$.asObservable()\n };\n }\n\n let replicationPrimitivesPush: ReplicationPushOptions | undefined;\n if (options.push) {\n const pushFilter = options.push?.filter;\n replicationPrimitivesPush = {\n async handler(\n rows: RxReplicationWriteToMasterRow[]\n ) {\n if (pushFilter !== undefined) {\n rows = await asyncFilter(rows, (row) => pushFilter(row.newDocumentState));\n }\n\n const writeRowsById: ById> = {};\n const docIds: string[] = rows.map(row => {\n const docId = (row.newDocumentState as any)[primaryPath];\n writeRowsById[docId] = row;\n return docId;\n });\n await waitForPendingWrites(options.firestore.database);\n let conflicts: WithDeleted[] = [];\n\n /**\n * Everything must run INSIDE of the transaction\n * because on tx-errors, firebase will re-run the transaction on some cases.\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#transaction_failure\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions\n */\n await runTransaction(options.firestore.database, async (_tx) => {\n conflicts = []; // reset in case the tx has re-run.\n /**\n * @link https://stackoverflow.com/a/48423626/3443137\n */\n\n const getQuery = (ids: string[]) => {\n return getDocs(\n query(\n options.firestore.collection,\n where(documentId(), 'in', ids)\n )\n );\n };\n\n const docsInDbResult = await getContentByIds(docIds, getQuery);\n\n const docsInDbById: ById = {};\n docsInDbResult.forEach(row => {\n const docDataInDb = stripServerTimestampField(serverTimestampField, row.data());\n const docId = row.id;\n (docDataInDb as any)[primaryPath] = docId;\n docsInDbById[docId] = docDataInDb;\n });\n\n /**\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n */\n const batch = writeBatch(options.firestore.database);\n let hasWrite = false;\n await Promise.all(\n Object.entries(writeRowsById).map(async ([docId, writeRow]) => {\n const docInDb: RxDocType | undefined = docsInDbById[docId];\n\n if (\n docInDb &&\n (\n !writeRow.assumedMasterState ||\n collection.conflictHandler.isEqual(docInDb as any, writeRow.assumedMasterState, 'replication-firestore-push') === false\n )\n ) {\n // conflict\n conflicts.push(docInDb as any);\n } else {\n // no conflict\n hasWrite = true;\n const docRef = doc(options.firestore.collection, docId);\n const writeDocData = flatClone(writeRow.newDocumentState);\n (writeDocData as any)[serverTimestampField] = serverTimestamp();\n if (!docInDb) {\n // insert\n batch.set(docRef, stripPrimaryKey(primaryPath, writeDocData));\n } else {\n // update\n batch.update(docRef, stripPrimaryKey(primaryPath, writeDocData));\n }\n }\n })\n );\n\n if (hasWrite) {\n await batch.commit();\n }\n });\n await waitForPendingWrites(options.firestore.database);\n return conflicts;\n },\n batchSize: options.push.batchSize,\n modifier: options.push.modifier\n };\n }\n\n\n const replicationState = new RxFirestoreReplicationState(\n options.firestore,\n options.replicationIdentifier,\n collection,\n replicationPrimitivesPull,\n replicationPrimitivesPush,\n options.live,\n options.retryTime,\n options.autoStart\n );\n\n /**\n * Use long polling to get live changes for the pull.stream$\n */\n if (options.live && options.pull) {\n const startBefore = replicationState.start.bind(replicationState);\n const cancelBefore = replicationState.cancel.bind(replicationState);\n replicationState.start = () => {\n const lastChangeQuery = query(\n pullQuery,\n orderBy(serverTimestampField, 'desc'),\n limit(1)\n );\n const unsubscribe = onSnapshot(\n lastChangeQuery,\n (_querySnapshot) => {\n /**\n * There is no good way to observe the event stream in firestore.\n * So instead we listen to any write to the collection\n * and then emit a 'RESYNC' flag.\n */\n replicationState.reSync();\n },\n (error) => {\n replicationState.subjects.error.next(\n newRxError('RC_STREAM', { error: errorToPlainJson(error) })\n );\n }\n );\n replicationState.cancel = () => {\n unsubscribe();\n return cancelBefore();\n };\n return startBefore();\n };\n }\n\n startReplicationOnLeaderShip(options.waitForLeadership, replicationState);\n\n return replicationState;\n}\n"],"mappings":";AAAA,SACIA,aAAa,EACbC,WAAW,EACXC,cAAc,EACdC,gBAAgB,EAChBC,SAAS,EACTC,WAAW,EACXC,OAAO,QACJ,8BAA8B;AAErC,SACIC,GAAG,EACHC,KAAK,EACLC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,OAAO,EACPC,UAAU,EACVC,cAAc,EACdC,UAAU,EACVC,eAAe,EAEfC,oBAAoB,EACpBC,UAAU,QACP,oBAAoB;AAE3B,SAASC,wBAAwB,QAAQ,6BAA6B;AAQtE,SACIC,kBAAkB,EAClBC,4BAA4B,QACzB,yBAAyB;AAChC,SACIC,WAAW,EAEXC,qBAAqB,EACrBC,UAAU,QAEP,gBAAgB;AAOvB,SAASC,OAAO,QAAQ,MAAM;AAC9B,SACIC,qBAAqB,EACrBC,eAAe,EACfC,0BAA0B,EAC1BC,0BAA0B,EAC1BC,eAAe,EACfC,yBAAyB,QACtB,uBAAuB;AAE9B,cAAc,uBAAuB;AACrC,cAAc,sBAAsB;AAEpC,WAAaC,2BAA2B,0BAAAC,mBAAA;EACpC,SAAAD,4BACoBE,SAAsC,EACtCC,yBAAiC,EACjCC,UAAmC,EACnCC,IAAiE,EACjEC,IAAwC,EACxCC,IAAa,GAAG,IAAI,EAC7BC,SAAiB,GAAG,IAAI,GAAG,CAAC,EAC5BC,SAAkB,GAAG,IAAI,EAClC;IAAA,IAAAC,KAAA;IACEA,KAAA,GAAAT,mBAAA,CAAAU,IAAA,OACIR,yBAAyB,EACzBC,UAAU,EACV,UAAU,EACVC,IAAI,EACJC,IAAI,EACJC,IAAI,EACJC,SAAS,EACTC,SACJ,CAAC;IAACC,KAAA,CAlBcR,SAAsC,GAAtCA,SAAsC;IAAAQ,KAAA,CACtCP,yBAAiC,GAAjCA,yBAAiC;IAAAO,KAAA,CACjCN,UAAmC,GAAnCA,UAAmC;IAAAM,KAAA,CACnCL,IAAiE,GAAjEA,IAAiE;IAAAK,KAAA,CACjEJ,IAAwC,GAAxCA,IAAwC;IAAAI,KAAA,CACxCH,IAAa,GAAbA,IAAa;IAAAG,KAAA,CACtBF,SAAiB,GAAjBA,SAAiB;IAAAE,KAAA,CACjBD,SAAkB,GAAlBA,SAAkB;IAAA,OAAAC,KAAA;EAY7B;EAACE,cAAA,CAAAZ,2BAAA,EAAAC,mBAAA;EAAA,OAAAD,2BAAA;AAAA,EArBuDZ,kBAAkB;AAwB9E,OAAO,SAASyB,kBAAkBA,CAC9BC,OAAwC,EACF;EACtC,IAAMV,UAAmC,GAAGU,OAAO,CAACV,UAAU;EAC9Dd,WAAW,CAACH,wBAAwB,CAAC;EACrC,IAAM4B,WAAqF,GAAG,IAAItB,OAAO,CAAC,CAAC;EAC3G,IAAIuB,yBAAiG;EACrGF,OAAO,CAACP,IAAI,GAAG,OAAOO,OAAO,CAACP,IAAI,KAAK,WAAW,GAAG,IAAI,GAAGO,OAAO,CAACP,IAAI;EACxEO,OAAO,CAACG,iBAAiB,GAAG,OAAOH,OAAO,CAACG,iBAAiB,KAAK,WAAW,GAAG,IAAI,GAAGH,OAAO,CAACG,iBAAiB;EAC/G,IAAMC,oBAAoB,GAAG,OAAOJ,OAAO,CAACI,oBAAoB,KAAK,WAAW,GAAG,iBAAiB,GAAGJ,OAAO,CAACI,oBAAoB;EACnIJ,OAAO,CAACI,oBAAoB,GAAGA,oBAAoB;EACnD,IAAMC,WAAW,GAAGf,UAAU,CAACgB,MAAM,CAACD,WAAW;;EAEjD;AACJ;AACA;EACI,IAAME,UAAU,GAAG9B,qBAAqB,CAACa,UAAU,CAACgB,MAAM,CAACE,UAAU,EAAEJ,oBAAoB,CAAC;EAC5F,IACIG,UAAU;EACV;EACAH,oBAAoB,CAACK,QAAQ,CAAC,GAAG,CAAC,EACpC;IACE,MAAM/B,UAAU,CAAC,KAAK,EAAE;MACpBgC,KAAK,EAAEN,oBAAoB;MAC3BE,MAAM,EAAEhB,UAAU,CAACgB,MAAM,CAACE;IAC9B,CAAC,CAAC;EACN;EAEA,IAAMG,WAAW,GAAGX,OAAO,CAACT,IAAI,EAAEqB,MAAM,KAAKC,SAAS,GAChDrD,OAAO,CAACwC,OAAO,CAACT,IAAI,CAACqB,MAAM,CAAC,GAC5B,EAAE;EAER,IAAME,SAAS,GAAGpD,KAAK,CAACsC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAAE,GAAGqB,WAAW,CAAC;EAErE,IAAIX,OAAO,CAACT,IAAI,EAAE;IACdW,yBAAyB,GAAG;MACxB,MAAMa,OAAOA,CACTC,oBAAyD,EACzDC,SAAiB,EACnB;QACE,IAAIC,UAAoC;QACxC,IAAIC,aAAmD;QAEvD,IAAIH,oBAAoB,EAAE;UACtB,IAAMI,mBAAmB,GAAGtC,0BAA0B,CAACkC,oBAAoB,CAAC9C,eAAe,CAAC;UAC5FgD,UAAU,GAAGxD,KAAK,CAACoD,SAAS,EACxBnD,KAAK,CAACyC,oBAAoB,EAAE,GAAG,EAAEgB,mBAAmB,CAAC,EACrDxD,OAAO,CAACwC,oBAAoB,EAAE,KAAK,CAAC,EACpCvC,KAAK,CAACoD,SAAS,CACnB,CAAC;UACDE,aAAa,GAAGzD,KAAK,CAACoD,SAAS,EAC3BnD,KAAK,CAACyC,oBAAoB,EAAE,IAAI,EAAEgB,mBAAmB,CAAC,EACtDzD,KAAK,CAACS,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE4C,oBAAoB,CAACK,EAAE,CAAC,EACjDzD,OAAO,CAACQ,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,EAC5BP,KAAK,CAACoD,SAAS,CACnB,CAAC;QACL,CAAC,MAAM;UACHC,UAAU,GAAGxD,KAAK,CAACoD,SAAS,EACxBlD,OAAO,CAACwC,oBAAoB,EAAE,KAAK,CAAC,EACpCvC,KAAK,CAACoD,SAAS,CACnB,CAAC;QACL;QAEA,IAAIK,UAAU,GAAG,IAAI;QACrB,IAAIC,OAA2C,GAAG,EAAE;QACpD,OAAOD,UAAU,EAAE;UACf;AACpB;AACA;AACA;AACA;AACA;UACoB,MAAMnD,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;UACtD,MAAMxD,cAAc,CAACgC,OAAO,CAACZ,SAAS,CAACoC,QAAQ,EAAE,MAAOC,GAAG,IAAK;YAC5DF,OAAO,GAAG,EAAE;YACZ,IAAM,CACFG,gBAAgB,EAChBC,mBAAmB,CACtB,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAClB/D,OAAO,CAACoD,UAAU,CAAC,EACnBC,aAAa,GAAGrD,OAAO,CAACqD,aAAa,CAAC,GAAGN,SAAS,CACrD,CAAC;YAEF,IACIa,gBAAgB,CAACI,QAAQ,CAACC,gBAAgB,IACzCZ,aAAa,IAAI/D,cAAc,CAACuE,mBAAmB,CAAC,CAACG,QAAQ,CAACC,gBAAiB,EAClF;cACE;YACJ,CAAC,MAAM;cACHT,UAAU,GAAG,KAAK;cAElB,IAAIH,aAAa,EAAE;gBACfI,OAAO,GAAGnE,cAAc,CAACuE,mBAAmB,CAAC,CAACK,IAAW;cAC7D;cACA,IAAMC,aAAa,GAAGhB,SAAS,GAAGM,OAAO,CAACW,MAAM;cAChD,IAAID,aAAa,GAAG,CAAC,EAAE;gBACnB,IAAME,cAAc,GAAGT,gBAAgB,CAACM,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEH,aAAa,CAAC,CAACrB,MAAM,CAACyB,CAAC,IAAI,CAAC,CAACA,CAAC,CAAC;gBACrFnF,aAAa,CAACqE,OAAO,EAAEY,cAAc,CAAC;cAC1C;YACJ;UACJ,CAAC,CAAC;QACN;QAEA,IAAIZ,OAAO,CAACW,MAAM,KAAK,CAAC,EAAE;UACtB,OAAO;YACHI,UAAU,EAAEtB,oBAAoB,IAAI,IAAI;YACxCuB,SAAS,EAAE;UACf,CAAC;QACL;QACA,IAAMC,OAAO,GAAGpF,cAAc,CAACG,WAAW,CAACgE,OAAO,CAAC,CAAC;QACpD,IAAMgB,SAAmC,GAAGhB,OAAO,CAC9CkB,GAAG,CAACC,GAAG,IAAI9D,qBAAqB,CAC7BwB,oBAAoB,EACpBC,WAAW,EACXqC,GACJ,CAAC,CAAC;QACN,IAAMC,aAAsC,GAAG;UAC3CtB,EAAE,EAAEmB,OAAO,CAACnB,EAAE;UACdnD,eAAe,EAAEa,0BAA0B,CAACqB,oBAAoB,EAAEoC,OAAO,CAACI,IAAI,CAAC,CAAC;QACpF,CAAC;QACD,IAAMC,GAAG,GAAG;UACRN,SAAS,EAAEA,SAAS;UACpBD,UAAU,EAAEK;QAChB,CAAC;QACD,OAAOE,GAAG;MACd,CAAC;MACD5B,SAAS,EAAE7D,cAAc,CAAC4C,OAAO,CAACT,IAAI,CAAC,CAAC0B,SAAS;MACjD6B,QAAQ,EAAE1F,cAAc,CAAC4C,OAAO,CAACT,IAAI,CAAC,CAACuD,QAAQ;MAC/CC,OAAO,EAAE9C,WAAW,CAAC+C,YAAY,CAAC;IACtC,CAAC;EACL;EAEA,IAAIC,yBAAwE;EAC5E,IAAIjD,OAAO,CAACR,IAAI,EAAE;IACd,IAAM0D,UAAU,GAAGlD,OAAO,CAACR,IAAI,EAAEoB,MAAM;IACvCqC,yBAAyB,GAAG;MACxB,MAAMlC,OAAOA,CACToC,IAAgD,EAClD;QACE,IAAID,UAAU,KAAKrC,SAAS,EAAE;UAC1BsC,IAAI,GAAG,MAAMhG,WAAW,CAACgG,IAAI,EAAGT,GAAG,IAAKQ,UAAU,CAACR,GAAG,CAACU,gBAAgB,CAAC,CAAC;QAC7E;QAEA,IAAMC,aAA6D,GAAG,CAAC,CAAC;QACxE,IAAMC,MAAgB,GAAGH,IAAI,CAACV,GAAG,CAACC,GAAG,IAAI;UACrC,IAAMa,KAAK,GAAIb,GAAG,CAACU,gBAAgB,CAAS/C,WAAW,CAAC;UACxDgD,aAAa,CAACE,KAAK,CAAC,GAAGb,GAAG;UAC1B,OAAOa,KAAK;QAChB,CAAC,CAAC;QACF,MAAMpF,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;QACtD,IAAIgC,SAAmC,GAAG,EAAE;;QAE5C;AAChB;AACA;AACA;AACA;AACA;QACgB,MAAMxF,cAAc,CAACgC,OAAO,CAACZ,SAAS,CAACoC,QAAQ,EAAE,MAAOC,GAAG,IAAK;UAC5D+B,SAAS,GAAG,EAAE,CAAC,CAAC;UAChB;AACpB;AACA;;UAEoB,IAAMC,QAAQ,GAAIC,GAAa,IAAK;YAChC,OAAO5F,OAAO,CACVJ,KAAK,CACDsC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAC5B3B,KAAK,CAACS,UAAU,CAAC,CAAC,EAAE,IAAI,EAAEsF,GAAG,CACjC,CACJ,CAAC;UACL,CAAC;UAED,IAAMC,cAAc,GAAG,MAAM9E,eAAe,CAAYyE,MAAM,EAAEG,QAAQ,CAAC;UAEzE,IAAMG,YAA6B,GAAG,CAAC,CAAC;UACxCD,cAAc,CAACE,OAAO,CAACnB,GAAG,IAAI;YAC1B,IAAMoB,WAAW,GAAG7E,yBAAyB,CAACmB,oBAAoB,EAAEsC,GAAG,CAACE,IAAI,CAAC,CAAC,CAAC;YAC/E,IAAMW,KAAK,GAAGb,GAAG,CAACrB,EAAE;YACnByC,WAAW,CAASzD,WAAW,CAAC,GAAGkD,KAAK;YACzCK,YAAY,CAACL,KAAK,CAAC,GAAGO,WAAW;UACrC,CAAC,CAAC;;UAEF;AACpB;AACA;UACoB,IAAMC,KAAK,GAAG9F,UAAU,CAAC+B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;UACpD,IAAIwC,QAAQ,GAAG,KAAK;UACpB,MAAMpC,OAAO,CAACC,GAAG,CACboC,MAAM,CAACC,OAAO,CAACb,aAAa,CAAC,CAACZ,GAAG,CAAC,OAAO,CAACc,KAAK,EAAEY,QAAQ,CAAC,KAAK;YAC3D,IAAMC,OAA8B,GAAGR,YAAY,CAACL,KAAK,CAAC;YAE1D,IACIa,OAAO,KAEH,CAACD,QAAQ,CAACE,kBAAkB,IAC5B/E,UAAU,CAACgF,eAAe,CAACC,OAAO,CAACH,OAAO,EAASD,QAAQ,CAACE,kBAAkB,EAAE,4BAA4B,CAAC,KAAK,KAAK,CAC1H,EACH;cACE;cACAb,SAAS,CAAChE,IAAI,CAAC4E,OAAc,CAAC;YAClC,CAAC,MAAM;cACH;cACAJ,QAAQ,GAAG,IAAI;cACf,IAAMQ,MAAM,GAAG/G,GAAG,CAACuC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAAEiE,KAAK,CAAC;cACvD,IAAMkB,YAAY,GAAGnH,SAAS,CAAC6G,QAAQ,CAACf,gBAAgB,CAAC;cACxDqB,YAAY,CAASrE,oBAAoB,CAAC,GAAGlC,eAAe,CAAC,CAAC;cAC/D,IAAI,CAACkG,OAAO,EAAE;gBACV;gBACAL,KAAK,CAACW,GAAG,CAACF,MAAM,EAAExF,eAAe,CAACqB,WAAW,EAAEoE,YAAY,CAAC,CAAC;cACjE,CAAC,MAAM;gBACH;gBACAV,KAAK,CAACY,MAAM,CAACH,MAAM,EAAExF,eAAe,CAACqB,WAAW,EAAEoE,YAAY,CAAC,CAAC;cACpE;YACJ;UACJ,CAAC,CACL,CAAC;UAED,IAAIT,QAAQ,EAAE;YACV,MAAMD,KAAK,CAACa,MAAM,CAAC,CAAC;UACxB;QACJ,CAAC,CAAC;QACF,MAAMzG,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;QACtD,OAAOgC,SAAS;MACpB,CAAC;MACDvC,SAAS,EAAEjB,OAAO,CAACR,IAAI,CAACyB,SAAS;MACjC6B,QAAQ,EAAE9C,OAAO,CAACR,IAAI,CAACsD;IAC3B,CAAC;EACL;EAGA,IAAM+B,gBAAgB,GAAG,IAAI3F,2BAA2B,CACpDc,OAAO,CAACZ,SAAS,EACjBY,OAAO,CAAC8E,qBAAqB,EAC7BxF,UAAU,EACVY,yBAAyB,EACzB+C,yBAAyB,EACzBjD,OAAO,CAACP,IAAI,EACZO,OAAO,CAACN,SAAS,EACjBM,OAAO,CAACL,SACZ,CAAC;;EAED;AACJ;AACA;EACI,IAAIK,OAAO,CAACP,IAAI,IAAIO,OAAO,CAACT,IAAI,EAAE;IAC9B,IAAMwF,WAAW,GAAGF,gBAAgB,CAACG,KAAK,CAACC,IAAI,CAACJ,gBAAgB,CAAC;IACjE,IAAMK,YAAY,GAAGL,gBAAgB,CAACM,MAAM,CAACF,IAAI,CAACJ,gBAAgB,CAAC;IACnEA,gBAAgB,CAACG,KAAK,GAAG,MAAM;MAC3B,IAAMI,eAAe,GAAG1H,KAAK,CACzBoD,SAAS,EACTlD,OAAO,CAACwC,oBAAoB,EAAE,MAAM,CAAC,EACrCvC,KAAK,CAAC,CAAC,CACX,CAAC;MACD,IAAMwH,WAAW,GAAGtH,UAAU,CAC1BqH,eAAe,EACdE,cAAc,IAAK;QAChB;AACpB;AACA;AACA;AACA;QACoBT,gBAAgB,CAACU,MAAM,CAAC,CAAC;MAC7B,CAAC,EACAC,KAAK,IAAK;QACPX,gBAAgB,CAACY,QAAQ,CAACD,KAAK,CAACE,IAAI,CAChChH,UAAU,CAAC,WAAW,EAAE;UAAE8G,KAAK,EAAEnI,gBAAgB,CAACmI,KAAK;QAAE,CAAC,CAC9D,CAAC;MACL,CACJ,CAAC;MACDX,gBAAgB,CAACM,MAAM,GAAG,MAAM;QAC5BE,WAAW,CAAC,CAAC;QACb,OAAOH,YAAY,CAAC,CAAC;MACzB,CAAC;MACD,OAAOH,WAAW,CAAC,CAAC;IACxB,CAAC;EACL;EAEAxG,4BAA4B,CAACyB,OAAO,CAACG,iBAAiB,EAAE0E,gBAAgB,CAAC;EAEzE,OAAOA,gBAAgB;AAC3B","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"index.js","names":["appendToArray","asyncFilter","ensureNotFalsy","errorToPlainJson","flatClone","lastOfArray","toArray","doc","query","where","orderBy","limit","getDocs","onSnapshot","runTransaction","writeBatch","serverTimestamp","waitForPendingWrites","documentId","RxDBLeaderElectionPlugin","RxReplicationState","startReplicationOnLeaderShip","addRxPlugin","getSchemaByObjectPath","newRxError","Subject","firestoreRowToDocData","getContentByIds","isoStringToServerTimestamp","serverTimestampToIsoString","stripPrimaryKey","stripServerTimestampField","RxFirestoreReplicationState","_RxReplicationState","firestore","replicationIdentifierHash","collection","pull","push","live","retryTime","autoStart","_this","call","_inheritsLoose","replicateFirestore","options","pullStream$","replicationPrimitivesPull","waitForLeadership","serverTimestampField","primaryPath","schema","schemaPart","jsonSchema","includes","field","pullFilters","filter","undefined","pullQuery","handler","lastPulledCheckpoint","batchSize","newerQuery","sameTimeQuery","lastServerTimestamp","id","mustsReRun","useDocs","database","_tx","newerQueryResult","sameTimeQueryResult","Promise","all","metadata","hasPendingWrites","docs","missingAmount","length","additionalDocs","slice","x","checkpoint","documents","lastDoc","map","row","newCheckpoint","data","ret","modifier","stream$","asObservable","initialCheckpoint","replicationPrimitivesPush","pushFilter","rows","newDocumentState","writeRowsById","docIds","docId","conflicts","getQuery","ids","docsInDbResult","docsInDbById","forEach","docDataInDb","batch","hasWrite","Object","entries","writeRow","docInDb","assumedMasterState","conflictHandler","isEqual","docRef","writeDocData","set","update","commit","replicationState","replicationIdentifier","startBefore","start","bind","cancelBefore","cancel","lastChangeQuery","unsubscribe","_querySnapshot","reSync","error","subjects","next"],"sources":["../../../../src/plugins/replication-firestore/index.ts"],"sourcesContent":["import {\n appendToArray,\n asyncFilter,\n ensureNotFalsy,\n errorToPlainJson,\n flatClone,\n lastOfArray,\n toArray\n} from '../../plugins/utils/index.ts';\n\nimport {\n doc,\n query,\n where,\n orderBy,\n limit,\n getDocs,\n onSnapshot,\n runTransaction,\n writeBatch,\n serverTimestamp,\n QueryDocumentSnapshot,\n waitForPendingWrites,\n documentId\n} from 'firebase/firestore';\n\nimport { RxDBLeaderElectionPlugin } from '../leader-election/index.ts';\nimport type {\n RxCollection,\n ReplicationPullOptions,\n ReplicationPushOptions,\n RxReplicationWriteToMasterRow,\n RxReplicationPullStreamItem\n} from '../../types/index.d.ts';\nimport {\n RxReplicationState,\n startReplicationOnLeaderShip\n} from '../replication/index.ts';\nimport {\n addRxPlugin,\n ById,\n getSchemaByObjectPath,\n newRxError,\n WithDeleted\n} from '../../index.ts';\n\nimport type {\n FirestoreCheckpointType,\n FirestoreOptions,\n SyncOptionsFirestore\n} from './firestore-types.ts';\nimport { Subject } from 'rxjs';\nimport {\n firestoreRowToDocData,\n getContentByIds,\n isoStringToServerTimestamp,\n serverTimestampToIsoString,\n stripPrimaryKey,\n stripServerTimestampField\n} from './firestore-helper.ts';\n\nexport * from './firestore-helper.ts';\nexport * from './firestore-types.ts';\n\nexport class RxFirestoreReplicationState extends RxReplicationState {\n constructor(\n public readonly firestore: FirestoreOptions,\n public readonly replicationIdentifierHash: string,\n public readonly collection: RxCollection,\n public readonly pull?: ReplicationPullOptions,\n public readonly push?: ReplicationPushOptions,\n public readonly live: boolean = true,\n public retryTime: number = 1000 * 5,\n public autoStart: boolean = true\n ) {\n super(\n replicationIdentifierHash,\n collection,\n '_deleted',\n pull,\n push,\n live,\n retryTime,\n autoStart\n );\n }\n}\n\nexport function replicateFirestore(\n options: SyncOptionsFirestore\n): RxFirestoreReplicationState {\n const collection: RxCollection = options.collection;\n addRxPlugin(RxDBLeaderElectionPlugin);\n const pullStream$: Subject> = new Subject();\n let replicationPrimitivesPull: ReplicationPullOptions | undefined;\n options.live = typeof options.live === 'undefined' ? true : options.live;\n options.waitForLeadership = typeof options.waitForLeadership === 'undefined' ? true : options.waitForLeadership;\n const serverTimestampField = typeof options.serverTimestampField === 'undefined' ? 'serverTimestamp' : options.serverTimestampField;\n options.serverTimestampField = serverTimestampField;\n const primaryPath = collection.schema.primaryPath;\n\n /**\n * The serverTimestampField MUST NOT be part of the collections RxJsonSchema.\n */\n const schemaPart = getSchemaByObjectPath(collection.schema.jsonSchema, serverTimestampField);\n if (\n schemaPart ||\n // also must not be nested.\n serverTimestampField.includes('.')\n ) {\n throw newRxError('RC6', {\n field: serverTimestampField,\n schema: collection.schema.jsonSchema\n });\n }\n\n const pullFilters = options.pull?.filter !== undefined\n ? toArray(options.pull.filter)\n : [];\n\n const pullQuery = query(options.firestore.collection, ...pullFilters);\n\n if (options.pull) {\n replicationPrimitivesPull = {\n async handler(\n lastPulledCheckpoint: FirestoreCheckpointType | undefined,\n batchSize: number\n ) {\n let newerQuery: ReturnType;\n let sameTimeQuery: ReturnType | undefined;\n\n if (lastPulledCheckpoint) {\n const lastServerTimestamp = isoStringToServerTimestamp(lastPulledCheckpoint.serverTimestamp);\n newerQuery = query(pullQuery,\n where(serverTimestampField, '>', lastServerTimestamp),\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n sameTimeQuery = query(pullQuery,\n where(serverTimestampField, '==', lastServerTimestamp),\n where(documentId(), '>', lastPulledCheckpoint.id),\n orderBy(documentId(), 'asc'),\n limit(batchSize)\n );\n } else {\n newerQuery = query(pullQuery,\n orderBy(serverTimestampField, 'asc'),\n limit(batchSize)\n );\n }\n\n let mustsReRun = true;\n let useDocs: QueryDocumentSnapshot[] = [];\n while (mustsReRun) {\n /**\n * Local writes that have not been persisted to the server\n * are in pending state and do not have a correct serverTimestamp set.\n * We have to ensure we only use document states that are in sync with the server.\n * @link https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b\n */\n await waitForPendingWrites(options.firestore.database);\n await runTransaction(options.firestore.database, async (_tx) => {\n useDocs = [];\n const [\n newerQueryResult,\n sameTimeQueryResult\n ] = await Promise.all([\n getDocs(newerQuery),\n sameTimeQuery ? getDocs(sameTimeQuery) : undefined\n ]);\n\n if (\n newerQueryResult.metadata.hasPendingWrites ||\n (sameTimeQuery && ensureNotFalsy(sameTimeQueryResult).metadata.hasPendingWrites)\n ) {\n return;\n } else {\n mustsReRun = false;\n\n if (sameTimeQuery) {\n useDocs = ensureNotFalsy(sameTimeQueryResult).docs as any;\n }\n const missingAmount = batchSize - useDocs.length;\n if (missingAmount > 0) {\n const additionalDocs = newerQueryResult.docs.slice(0, missingAmount).filter(x => !!x);\n appendToArray(useDocs, additionalDocs);\n }\n }\n });\n }\n\n if (useDocs.length === 0) {\n return {\n checkpoint: lastPulledCheckpoint ?? null,\n documents: []\n };\n }\n const lastDoc = ensureNotFalsy(lastOfArray(useDocs));\n const documents: WithDeleted[] = useDocs\n .map(row => firestoreRowToDocData(\n serverTimestampField,\n primaryPath,\n row\n ));\n const newCheckpoint: FirestoreCheckpointType = {\n id: lastDoc.id,\n serverTimestamp: serverTimestampToIsoString(serverTimestampField, lastDoc.data())\n };\n const ret = {\n documents: documents,\n checkpoint: newCheckpoint\n };\n return ret;\n },\n batchSize: ensureNotFalsy(options.pull).batchSize,\n modifier: ensureNotFalsy(options.pull).modifier,\n stream$: pullStream$.asObservable(),\n initialCheckpoint: options.pull.initialCheckpoint\n };\n }\n\n let replicationPrimitivesPush: ReplicationPushOptions | undefined;\n if (options.push) {\n const pushFilter = options.push?.filter;\n replicationPrimitivesPush = {\n async handler(\n rows: RxReplicationWriteToMasterRow[]\n ) {\n if (pushFilter !== undefined) {\n rows = await asyncFilter(rows, (row) => pushFilter(row.newDocumentState));\n }\n\n const writeRowsById: ById> = {};\n const docIds: string[] = rows.map(row => {\n const docId = (row.newDocumentState as any)[primaryPath];\n writeRowsById[docId] = row;\n return docId;\n });\n await waitForPendingWrites(options.firestore.database);\n let conflicts: WithDeleted[] = [];\n\n /**\n * Everything must run INSIDE of the transaction\n * because on tx-errors, firebase will re-run the transaction on some cases.\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#transaction_failure\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions\n */\n await runTransaction(options.firestore.database, async (_tx) => {\n conflicts = []; // reset in case the tx has re-run.\n /**\n * @link https://stackoverflow.com/a/48423626/3443137\n */\n\n const getQuery = (ids: string[]) => {\n return getDocs(\n query(\n options.firestore.collection,\n where(documentId(), 'in', ids)\n )\n );\n };\n\n const docsInDbResult = await getContentByIds(docIds, getQuery);\n\n const docsInDbById: ById = {};\n docsInDbResult.forEach(row => {\n const docDataInDb = stripServerTimestampField(serverTimestampField, row.data());\n const docId = row.id;\n (docDataInDb as any)[primaryPath] = docId;\n docsInDbById[docId] = docDataInDb;\n });\n\n /**\n * @link https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n */\n const batch = writeBatch(options.firestore.database);\n let hasWrite = false;\n await Promise.all(\n Object.entries(writeRowsById).map(async ([docId, writeRow]) => {\n const docInDb: RxDocType | undefined = docsInDbById[docId];\n\n if (\n docInDb &&\n (\n !writeRow.assumedMasterState ||\n collection.conflictHandler.isEqual(docInDb as any, writeRow.assumedMasterState, 'replication-firestore-push') === false\n )\n ) {\n // conflict\n conflicts.push(docInDb as any);\n } else {\n // no conflict\n hasWrite = true;\n const docRef = doc(options.firestore.collection, docId);\n const writeDocData = flatClone(writeRow.newDocumentState);\n (writeDocData as any)[serverTimestampField] = serverTimestamp();\n if (!docInDb) {\n // insert\n batch.set(docRef, stripPrimaryKey(primaryPath, writeDocData));\n } else {\n // update\n batch.update(docRef, stripPrimaryKey(primaryPath, writeDocData));\n }\n }\n })\n );\n\n if (hasWrite) {\n await batch.commit();\n }\n });\n await waitForPendingWrites(options.firestore.database);\n return conflicts;\n },\n batchSize: options.push.batchSize,\n modifier: options.push.modifier\n };\n }\n\n\n const replicationState = new RxFirestoreReplicationState(\n options.firestore,\n options.replicationIdentifier,\n collection,\n replicationPrimitivesPull,\n replicationPrimitivesPush,\n options.live,\n options.retryTime,\n options.autoStart\n );\n\n /**\n * Use long polling to get live changes for the pull.stream$\n */\n if (options.live && options.pull) {\n const startBefore = replicationState.start.bind(replicationState);\n const cancelBefore = replicationState.cancel.bind(replicationState);\n replicationState.start = () => {\n const lastChangeQuery = query(\n pullQuery,\n orderBy(serverTimestampField, 'desc'),\n limit(1)\n );\n const unsubscribe = onSnapshot(\n lastChangeQuery,\n (_querySnapshot) => {\n /**\n * There is no good way to observe the event stream in firestore.\n * So instead we listen to any write to the collection\n * and then emit a 'RESYNC' flag.\n */\n replicationState.reSync();\n },\n (error) => {\n replicationState.subjects.error.next(\n newRxError('RC_STREAM', { error: errorToPlainJson(error) })\n );\n }\n );\n replicationState.cancel = () => {\n unsubscribe();\n return cancelBefore();\n };\n return startBefore();\n };\n }\n\n startReplicationOnLeaderShip(options.waitForLeadership, replicationState);\n\n return replicationState;\n}\n"],"mappings":";AAAA,SACIA,aAAa,EACbC,WAAW,EACXC,cAAc,EACdC,gBAAgB,EAChBC,SAAS,EACTC,WAAW,EACXC,OAAO,QACJ,8BAA8B;AAErC,SACIC,GAAG,EACHC,KAAK,EACLC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,OAAO,EACPC,UAAU,EACVC,cAAc,EACdC,UAAU,EACVC,eAAe,EAEfC,oBAAoB,EACpBC,UAAU,QACP,oBAAoB;AAE3B,SAASC,wBAAwB,QAAQ,6BAA6B;AAQtE,SACIC,kBAAkB,EAClBC,4BAA4B,QACzB,yBAAyB;AAChC,SACIC,WAAW,EAEXC,qBAAqB,EACrBC,UAAU,QAEP,gBAAgB;AAOvB,SAASC,OAAO,QAAQ,MAAM;AAC9B,SACIC,qBAAqB,EACrBC,eAAe,EACfC,0BAA0B,EAC1BC,0BAA0B,EAC1BC,eAAe,EACfC,yBAAyB,QACtB,uBAAuB;AAE9B,cAAc,uBAAuB;AACrC,cAAc,sBAAsB;AAEpC,WAAaC,2BAA2B,0BAAAC,mBAAA;EACpC,SAAAD,4BACoBE,SAAsC,EACtCC,yBAAiC,EACjCC,UAAmC,EACnCC,IAAiE,EACjEC,IAAwC,EACxCC,IAAa,GAAG,IAAI,EAC7BC,SAAiB,GAAG,IAAI,GAAG,CAAC,EAC5BC,SAAkB,GAAG,IAAI,EAClC;IAAA,IAAAC,KAAA;IACEA,KAAA,GAAAT,mBAAA,CAAAU,IAAA,OACIR,yBAAyB,EACzBC,UAAU,EACV,UAAU,EACVC,IAAI,EACJC,IAAI,EACJC,IAAI,EACJC,SAAS,EACTC,SACJ,CAAC;IAACC,KAAA,CAlBcR,SAAsC,GAAtCA,SAAsC;IAAAQ,KAAA,CACtCP,yBAAiC,GAAjCA,yBAAiC;IAAAO,KAAA,CACjCN,UAAmC,GAAnCA,UAAmC;IAAAM,KAAA,CACnCL,IAAiE,GAAjEA,IAAiE;IAAAK,KAAA,CACjEJ,IAAwC,GAAxCA,IAAwC;IAAAI,KAAA,CACxCH,IAAa,GAAbA,IAAa;IAAAG,KAAA,CACtBF,SAAiB,GAAjBA,SAAiB;IAAAE,KAAA,CACjBD,SAAkB,GAAlBA,SAAkB;IAAA,OAAAC,KAAA;EAY7B;EAACE,cAAA,CAAAZ,2BAAA,EAAAC,mBAAA;EAAA,OAAAD,2BAAA;AAAA,EArBuDZ,kBAAkB;AAwB9E,OAAO,SAASyB,kBAAkBA,CAC9BC,OAAwC,EACF;EACtC,IAAMV,UAAmC,GAAGU,OAAO,CAACV,UAAU;EAC9Dd,WAAW,CAACH,wBAAwB,CAAC;EACrC,IAAM4B,WAAqF,GAAG,IAAItB,OAAO,CAAC,CAAC;EAC3G,IAAIuB,yBAAiG;EACrGF,OAAO,CAACP,IAAI,GAAG,OAAOO,OAAO,CAACP,IAAI,KAAK,WAAW,GAAG,IAAI,GAAGO,OAAO,CAACP,IAAI;EACxEO,OAAO,CAACG,iBAAiB,GAAG,OAAOH,OAAO,CAACG,iBAAiB,KAAK,WAAW,GAAG,IAAI,GAAGH,OAAO,CAACG,iBAAiB;EAC/G,IAAMC,oBAAoB,GAAG,OAAOJ,OAAO,CAACI,oBAAoB,KAAK,WAAW,GAAG,iBAAiB,GAAGJ,OAAO,CAACI,oBAAoB;EACnIJ,OAAO,CAACI,oBAAoB,GAAGA,oBAAoB;EACnD,IAAMC,WAAW,GAAGf,UAAU,CAACgB,MAAM,CAACD,WAAW;;EAEjD;AACJ;AACA;EACI,IAAME,UAAU,GAAG9B,qBAAqB,CAACa,UAAU,CAACgB,MAAM,CAACE,UAAU,EAAEJ,oBAAoB,CAAC;EAC5F,IACIG,UAAU;EACV;EACAH,oBAAoB,CAACK,QAAQ,CAAC,GAAG,CAAC,EACpC;IACE,MAAM/B,UAAU,CAAC,KAAK,EAAE;MACpBgC,KAAK,EAAEN,oBAAoB;MAC3BE,MAAM,EAAEhB,UAAU,CAACgB,MAAM,CAACE;IAC9B,CAAC,CAAC;EACN;EAEA,IAAMG,WAAW,GAAGX,OAAO,CAACT,IAAI,EAAEqB,MAAM,KAAKC,SAAS,GAChDrD,OAAO,CAACwC,OAAO,CAACT,IAAI,CAACqB,MAAM,CAAC,GAC5B,EAAE;EAER,IAAME,SAAS,GAAGpD,KAAK,CAACsC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAAE,GAAGqB,WAAW,CAAC;EAErE,IAAIX,OAAO,CAACT,IAAI,EAAE;IACdW,yBAAyB,GAAG;MACxB,MAAMa,OAAOA,CACTC,oBAAyD,EACzDC,SAAiB,EACnB;QACE,IAAIC,UAAoC;QACxC,IAAIC,aAAmD;QAEvD,IAAIH,oBAAoB,EAAE;UACtB,IAAMI,mBAAmB,GAAGtC,0BAA0B,CAACkC,oBAAoB,CAAC9C,eAAe,CAAC;UAC5FgD,UAAU,GAAGxD,KAAK,CAACoD,SAAS,EACxBnD,KAAK,CAACyC,oBAAoB,EAAE,GAAG,EAAEgB,mBAAmB,CAAC,EACrDxD,OAAO,CAACwC,oBAAoB,EAAE,KAAK,CAAC,EACpCvC,KAAK,CAACoD,SAAS,CACnB,CAAC;UACDE,aAAa,GAAGzD,KAAK,CAACoD,SAAS,EAC3BnD,KAAK,CAACyC,oBAAoB,EAAE,IAAI,EAAEgB,mBAAmB,CAAC,EACtDzD,KAAK,CAACS,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE4C,oBAAoB,CAACK,EAAE,CAAC,EACjDzD,OAAO,CAACQ,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,EAC5BP,KAAK,CAACoD,SAAS,CACnB,CAAC;QACL,CAAC,MAAM;UACHC,UAAU,GAAGxD,KAAK,CAACoD,SAAS,EACxBlD,OAAO,CAACwC,oBAAoB,EAAE,KAAK,CAAC,EACpCvC,KAAK,CAACoD,SAAS,CACnB,CAAC;QACL;QAEA,IAAIK,UAAU,GAAG,IAAI;QACrB,IAAIC,OAA2C,GAAG,EAAE;QACpD,OAAOD,UAAU,EAAE;UACf;AACpB;AACA;AACA;AACA;AACA;UACoB,MAAMnD,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;UACtD,MAAMxD,cAAc,CAACgC,OAAO,CAACZ,SAAS,CAACoC,QAAQ,EAAE,MAAOC,GAAG,IAAK;YAC5DF,OAAO,GAAG,EAAE;YACZ,IAAM,CACFG,gBAAgB,EAChBC,mBAAmB,CACtB,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAClB/D,OAAO,CAACoD,UAAU,CAAC,EACnBC,aAAa,GAAGrD,OAAO,CAACqD,aAAa,CAAC,GAAGN,SAAS,CACrD,CAAC;YAEF,IACIa,gBAAgB,CAACI,QAAQ,CAACC,gBAAgB,IACzCZ,aAAa,IAAI/D,cAAc,CAACuE,mBAAmB,CAAC,CAACG,QAAQ,CAACC,gBAAiB,EAClF;cACE;YACJ,CAAC,MAAM;cACHT,UAAU,GAAG,KAAK;cAElB,IAAIH,aAAa,EAAE;gBACfI,OAAO,GAAGnE,cAAc,CAACuE,mBAAmB,CAAC,CAACK,IAAW;cAC7D;cACA,IAAMC,aAAa,GAAGhB,SAAS,GAAGM,OAAO,CAACW,MAAM;cAChD,IAAID,aAAa,GAAG,CAAC,EAAE;gBACnB,IAAME,cAAc,GAAGT,gBAAgB,CAACM,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEH,aAAa,CAAC,CAACrB,MAAM,CAACyB,CAAC,IAAI,CAAC,CAACA,CAAC,CAAC;gBACrFnF,aAAa,CAACqE,OAAO,EAAEY,cAAc,CAAC;cAC1C;YACJ;UACJ,CAAC,CAAC;QACN;QAEA,IAAIZ,OAAO,CAACW,MAAM,KAAK,CAAC,EAAE;UACtB,OAAO;YACHI,UAAU,EAAEtB,oBAAoB,IAAI,IAAI;YACxCuB,SAAS,EAAE;UACf,CAAC;QACL;QACA,IAAMC,OAAO,GAAGpF,cAAc,CAACG,WAAW,CAACgE,OAAO,CAAC,CAAC;QACpD,IAAMgB,SAAmC,GAAGhB,OAAO,CAC9CkB,GAAG,CAACC,GAAG,IAAI9D,qBAAqB,CAC7BwB,oBAAoB,EACpBC,WAAW,EACXqC,GACJ,CAAC,CAAC;QACN,IAAMC,aAAsC,GAAG;UAC3CtB,EAAE,EAAEmB,OAAO,CAACnB,EAAE;UACdnD,eAAe,EAAEa,0BAA0B,CAACqB,oBAAoB,EAAEoC,OAAO,CAACI,IAAI,CAAC,CAAC;QACpF,CAAC;QACD,IAAMC,GAAG,GAAG;UACRN,SAAS,EAAEA,SAAS;UACpBD,UAAU,EAAEK;QAChB,CAAC;QACD,OAAOE,GAAG;MACd,CAAC;MACD5B,SAAS,EAAE7D,cAAc,CAAC4C,OAAO,CAACT,IAAI,CAAC,CAAC0B,SAAS;MACjD6B,QAAQ,EAAE1F,cAAc,CAAC4C,OAAO,CAACT,IAAI,CAAC,CAACuD,QAAQ;MAC/CC,OAAO,EAAE9C,WAAW,CAAC+C,YAAY,CAAC,CAAC;MACnCC,iBAAiB,EAAEjD,OAAO,CAACT,IAAI,CAAC0D;IACpC,CAAC;EACL;EAEA,IAAIC,yBAAwE;EAC5E,IAAIlD,OAAO,CAACR,IAAI,EAAE;IACd,IAAM2D,UAAU,GAAGnD,OAAO,CAACR,IAAI,EAAEoB,MAAM;IACvCsC,yBAAyB,GAAG;MACxB,MAAMnC,OAAOA,CACTqC,IAAgD,EAClD;QACE,IAAID,UAAU,KAAKtC,SAAS,EAAE;UAC1BuC,IAAI,GAAG,MAAMjG,WAAW,CAACiG,IAAI,EAAGV,GAAG,IAAKS,UAAU,CAACT,GAAG,CAACW,gBAAgB,CAAC,CAAC;QAC7E;QAEA,IAAMC,aAA6D,GAAG,CAAC,CAAC;QACxE,IAAMC,MAAgB,GAAGH,IAAI,CAACX,GAAG,CAACC,GAAG,IAAI;UACrC,IAAMc,KAAK,GAAId,GAAG,CAACW,gBAAgB,CAAShD,WAAW,CAAC;UACxDiD,aAAa,CAACE,KAAK,CAAC,GAAGd,GAAG;UAC1B,OAAOc,KAAK;QAChB,CAAC,CAAC;QACF,MAAMrF,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;QACtD,IAAIiC,SAAmC,GAAG,EAAE;;QAE5C;AAChB;AACA;AACA;AACA;AACA;QACgB,MAAMzF,cAAc,CAACgC,OAAO,CAACZ,SAAS,CAACoC,QAAQ,EAAE,MAAOC,GAAG,IAAK;UAC5DgC,SAAS,GAAG,EAAE,CAAC,CAAC;UAChB;AACpB;AACA;;UAEoB,IAAMC,QAAQ,GAAIC,GAAa,IAAK;YAChC,OAAO7F,OAAO,CACVJ,KAAK,CACDsC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAC5B3B,KAAK,CAACS,UAAU,CAAC,CAAC,EAAE,IAAI,EAAEuF,GAAG,CACjC,CACJ,CAAC;UACL,CAAC;UAED,IAAMC,cAAc,GAAG,MAAM/E,eAAe,CAAY0E,MAAM,EAAEG,QAAQ,CAAC;UAEzE,IAAMG,YAA6B,GAAG,CAAC,CAAC;UACxCD,cAAc,CAACE,OAAO,CAACpB,GAAG,IAAI;YAC1B,IAAMqB,WAAW,GAAG9E,yBAAyB,CAACmB,oBAAoB,EAAEsC,GAAG,CAACE,IAAI,CAAC,CAAC,CAAC;YAC/E,IAAMY,KAAK,GAAGd,GAAG,CAACrB,EAAE;YACnB0C,WAAW,CAAS1D,WAAW,CAAC,GAAGmD,KAAK;YACzCK,YAAY,CAACL,KAAK,CAAC,GAAGO,WAAW;UACrC,CAAC,CAAC;;UAEF;AACpB;AACA;UACoB,IAAMC,KAAK,GAAG/F,UAAU,CAAC+B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;UACpD,IAAIyC,QAAQ,GAAG,KAAK;UACpB,MAAMrC,OAAO,CAACC,GAAG,CACbqC,MAAM,CAACC,OAAO,CAACb,aAAa,CAAC,CAACb,GAAG,CAAC,OAAO,CAACe,KAAK,EAAEY,QAAQ,CAAC,KAAK;YAC3D,IAAMC,OAA8B,GAAGR,YAAY,CAACL,KAAK,CAAC;YAE1D,IACIa,OAAO,KAEH,CAACD,QAAQ,CAACE,kBAAkB,IAC5BhF,UAAU,CAACiF,eAAe,CAACC,OAAO,CAACH,OAAO,EAASD,QAAQ,CAACE,kBAAkB,EAAE,4BAA4B,CAAC,KAAK,KAAK,CAC1H,EACH;cACE;cACAb,SAAS,CAACjE,IAAI,CAAC6E,OAAc,CAAC;YAClC,CAAC,MAAM;cACH;cACAJ,QAAQ,GAAG,IAAI;cACf,IAAMQ,MAAM,GAAGhH,GAAG,CAACuC,OAAO,CAACZ,SAAS,CAACE,UAAU,EAAEkE,KAAK,CAAC;cACvD,IAAMkB,YAAY,GAAGpH,SAAS,CAAC8G,QAAQ,CAACf,gBAAgB,CAAC;cACxDqB,YAAY,CAAStE,oBAAoB,CAAC,GAAGlC,eAAe,CAAC,CAAC;cAC/D,IAAI,CAACmG,OAAO,EAAE;gBACV;gBACAL,KAAK,CAACW,GAAG,CAACF,MAAM,EAAEzF,eAAe,CAACqB,WAAW,EAAEqE,YAAY,CAAC,CAAC;cACjE,CAAC,MAAM;gBACH;gBACAV,KAAK,CAACY,MAAM,CAACH,MAAM,EAAEzF,eAAe,CAACqB,WAAW,EAAEqE,YAAY,CAAC,CAAC;cACpE;YACJ;UACJ,CAAC,CACL,CAAC;UAED,IAAIT,QAAQ,EAAE;YACV,MAAMD,KAAK,CAACa,MAAM,CAAC,CAAC;UACxB;QACJ,CAAC,CAAC;QACF,MAAM1G,oBAAoB,CAAC6B,OAAO,CAACZ,SAAS,CAACoC,QAAQ,CAAC;QACtD,OAAOiC,SAAS;MACpB,CAAC;MACDxC,SAAS,EAAEjB,OAAO,CAACR,IAAI,CAACyB,SAAS;MACjC6B,QAAQ,EAAE9C,OAAO,CAACR,IAAI,CAACsD;IAC3B,CAAC;EACL;EAGA,IAAMgC,gBAAgB,GAAG,IAAI5F,2BAA2B,CACpDc,OAAO,CAACZ,SAAS,EACjBY,OAAO,CAAC+E,qBAAqB,EAC7BzF,UAAU,EACVY,yBAAyB,EACzBgD,yBAAyB,EACzBlD,OAAO,CAACP,IAAI,EACZO,OAAO,CAACN,SAAS,EACjBM,OAAO,CAACL,SACZ,CAAC;;EAED;AACJ;AACA;EACI,IAAIK,OAAO,CAACP,IAAI,IAAIO,OAAO,CAACT,IAAI,EAAE;IAC9B,IAAMyF,WAAW,GAAGF,gBAAgB,CAACG,KAAK,CAACC,IAAI,CAACJ,gBAAgB,CAAC;IACjE,IAAMK,YAAY,GAAGL,gBAAgB,CAACM,MAAM,CAACF,IAAI,CAACJ,gBAAgB,CAAC;IACnEA,gBAAgB,CAACG,KAAK,GAAG,MAAM;MAC3B,IAAMI,eAAe,GAAG3H,KAAK,CACzBoD,SAAS,EACTlD,OAAO,CAACwC,oBAAoB,EAAE,MAAM,CAAC,EACrCvC,KAAK,CAAC,CAAC,CACX,CAAC;MACD,IAAMyH,WAAW,GAAGvH,UAAU,CAC1BsH,eAAe,EACdE,cAAc,IAAK;QAChB;AACpB;AACA;AACA;AACA;QACoBT,gBAAgB,CAACU,MAAM,CAAC,CAAC;MAC7B,CAAC,EACAC,KAAK,IAAK;QACPX,gBAAgB,CAACY,QAAQ,CAACD,KAAK,CAACE,IAAI,CAChCjH,UAAU,CAAC,WAAW,EAAE;UAAE+G,KAAK,EAAEpI,gBAAgB,CAACoI,KAAK;QAAE,CAAC,CAC9D,CAAC;MACL,CACJ,CAAC;MACDX,gBAAgB,CAACM,MAAM,GAAG,MAAM;QAC5BE,WAAW,CAAC,CAAC;QACb,OAAOH,YAAY,CAAC,CAAC;MACzB,CAAC;MACD,OAAOH,WAAW,CAAC,CAAC;IACxB,CAAC;EACL;EAEAzG,4BAA4B,CAACyB,OAAO,CAACG,iBAAiB,EAAE2E,gBAAgB,CAAC;EAEzE,OAAOA,gBAAgB;AAC3B","ignoreList":[]} \ No newline at end of file diff --git a/docs/404.html b/docs/404.html index 4e3a6bbbc57..1601f854655 100644 --- a/docs/404.html +++ b/docs/404.html @@ -10,13 +10,13 @@ - - + + -

RxDB
404 Page Not Found

The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it.

Maybe one of these can help you to find the desired content:

+

RxDB
404 Page Not Found

The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it.

Maybe one of these can help you to find the desired content:

\ No newline at end of file diff --git a/docs/adapters.html b/docs/adapters.html index 42900d54192..cf797ff6fc4 100644 --- a/docs/adapters.html +++ b/docs/adapters.html @@ -10,14 +10,14 @@ - - + + -

PouchDB Adapters

+

PouchDB Adapters

When you use PouchDB RxStorage, there are many adapters that define where the data has to be stored. Depending on which environment you work in, you can choose between different adapters. For example, in the browser you want to store the data inside of IndexedDB but on NodeJS you want to store the data on the filesystem.

This page is an overview over the different adapters with recommendations on what to use where.

@@ -78,6 +78,6 @@

asyncstora

Cordova / Phonegap / Capacitor

cordova-sqlite

Uses cordova's global cordova.sqlitePlugin. It can be used with cordova and capacitor.

-
// npm install pouchdb-adapter-cordova-sqlite --save
addPouchPlugin(require('pouchdb-adapter-cordova-sqlite'));

/**
* In capacitor/cordova you have to wait until all plugins are loaded and 'window.sqlitePlugin'
* can be accessed.
* This function waits until document deviceready is called which ensures that everything is loaded.
* @link https://cordova.apache.org/docs/de/latest/cordova/events/events.deviceready.html
*/
export function awaitCapacitorDeviceReady(): Promise<void> {
return new Promise(res => {
document.addEventListener('deviceready', () => {
res();
});
});
}

async function getDatabase(){

// first wait until the deviceready event is fired
await awaitCapacitorDeviceReady();

const database = await createRxDatabase({
name: 'mydatabase',
storage: getRxStoragePouch(
'cordova-sqlite',
// pouch settings are passed as second parameter
{
// for ios devices, the cordova-sqlite adapter needs to know where to save the data.
iosDatabaseLocation: 'Library'
}
)
});
}
+
// npm install pouchdb-adapter-cordova-sqlite --save
addPouchPlugin(require('pouchdb-adapter-cordova-sqlite'));

/**
* In capacitor/cordova you have to wait until all plugins are loaded and 'window.sqlitePlugin'
* can be accessed.
* This function waits until document deviceready is called which ensures that everything is loaded.
* @link https://cordova.apache.org/docs/de/latest/cordova/events/events.deviceready.html
*/
export function awaitCapacitorDeviceReady(): Promise<void> {
return new Promise(res => {
document.addEventListener('deviceready', () => {
res();
});
});
}

async function getDatabase(){

// first wait until the deviceready event is fired
await awaitCapacitorDeviceReady();

const database = await createRxDatabase({
name: 'mydatabase',
storage: getRxStoragePouch(
'cordova-sqlite',
// pouch settings are passed as second parameter
{
// for ios devices, the cordova-sqlite adapter needs to know where to save the data.
iosDatabaseLocation: 'Library'
}
)
});
}
\ No newline at end of file diff --git a/docs/alternatives.html b/docs/alternatives.html index 5deef5facbe..65d278eec3d 100644 --- a/docs/alternatives.html +++ b/docs/alternatives.html @@ -10,14 +10,14 @@ - - + + -

Alternatives for realtime offline-first JavaScript applications

+

Alternatives for realtime offline-first JavaScript applications

To give you an augmented view over the topic of client side JavaScript databases, this page contains all known alternatives to RxDB. Remember that you are reading this inside of the RxDB documentation, so everything is opinionated. If you disagree with anything or think that something is missing, make a pull request to this file on the RxDB github repository.

note

RxDB has these main benefits:

+
\ No newline at end of file diff --git a/docs/articles/angular-database.html b/docs/articles/angular-database.html index e150352d6fb..fc3fc4f8e6f 100644 --- a/docs/articles/angular-database.html +++ b/docs/articles/angular-database.html @@ -10,14 +10,14 @@ - - + + -

RxDB as a Database in an Angular Application

+

RxDB as a Database in an Angular Application

In modern web development, Angular has emerged as a popular framework for building robust and scalable applications. As Angular applications often require persistent storage and efficient data handling, choosing the right database solution is crucial. One such solution is RxDB, a reactive JavaScript database for the browser, node.js, and mobile devices. In this article, we will explore the integration of RxDB into an Angular application and examine its various features and techniques.

JavaScript Angular Database

Angular Web Applications

@@ -113,6 +113,6 @@

Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which provides step-by-step instructions for setting up and using RxDB in your projects.
  • RxDB Angular Example at GitHub
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/angular-indexeddb.html b/docs/articles/angular-indexeddb.html index 0d8d0e231b0..9784cf42252 100644 --- a/docs/articles/angular-indexeddb.html +++ b/docs/articles/angular-indexeddb.html @@ -10,14 +10,14 @@ - - + + -

    Build Smarter Offline-First Angular Apps: How RxDB Beats IndexedDB Alone

    +

    Build Smarter Offline-First Angular Apps: How RxDB Beats IndexedDB Alone

    In modern web applications, offline capabilities and fast interactions are crucial. IndexedDB, the browser's built-in database, allows you to store data locally, making your Angular application more robust and responsive. However, IndexedDB can be cumbersome to work with directly. That's where RxDB (Reactive Database) shines. In this article, we'll walk you through how to utilize IndexedDB in your Angular project using RxDB as a convenient abstraction layer.

    What Is IndexedDB?

    IndexedDB is a low-level JavaScript API for client-side storage of large amounts of structured data. It allows you to create key-value or object store-based data storage right in the user's browser. IndexedDB supports transactions and indexing but lacks a robust query API and can be complex to use due to its callback-based nature.

    @@ -146,6 +146,6 @@

    Follow UpRxDB GitHub Repo.

    -

    By combining IndexedDB's local storage with RxDB's powerful features, you can build performant, robust, and offline-capable Angular applications. RxDB takes care of the lower-level complexities, letting you focus on delivering a great user experience-online or off.

    +

    By combining IndexedDB's local storage with RxDB's powerful features, you can build performant, robust, and offline-capable Angular applications. RxDB takes care of the lower-level complexities, letting you focus on delivering a great user experience-online or off.

    \ No newline at end of file diff --git a/docs/articles/browser-database.html b/docs/articles/browser-database.html index f719e8f97a4..1df4e2768f1 100644 --- a/docs/articles/browser-database.html +++ b/docs/articles/browser-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB: The benefits of Browser Databases

    +

    RxDB: The benefits of Browser Databases

    In the world of web development, efficient data management is a cornerstone of building successful and performant applications. The ability to store data directly in the browser brings numerous advantages, such as caching, offline accessibility, simplified replication of database state, and real-time application development. In this article, we will explore RxDB, a powerful browser JavaScript database, and understand why it is an excellent choice for implementing a browser database solution.

    JavaScript Browser Database

    Why you might want to store data in the browser

    @@ -85,6 +85,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which provides step-by-step instructions for setting up and using RxDB in your projects.
  • -

    RxDB empowers developers to unlock the power of browser databases, enabling efficient data management, real-time applications, and enhanced user experiences. By leveraging RxDB's features and benefits, you can take your browser-based applications to the next level of performance, scalability, and responsiveness.

    +

    RxDB empowers developers to unlock the power of browser databases, enabling efficient data management, real-time applications, and enhanced user experiences. By leveraging RxDB's features and benefits, you can take your browser-based applications to the next level of performance, scalability, and responsiveness.

    \ No newline at end of file diff --git a/docs/articles/browser-storage.html b/docs/articles/browser-storage.html index a86ae67c0ae..fb2244e57bf 100644 --- a/docs/articles/browser-storage.html +++ b/docs/articles/browser-storage.html @@ -10,14 +10,14 @@ - - + + -

    Browser Storage - RxDB as a Database for Browsers

    +

    Browser Storage - RxDB as a Database for Browsers

    Storing Data in the Browser

    When it comes to building web applications, one essential aspect is the storage of data. Two common methods of storing data directly within the user's web browser are Localstorage and IndexedDB. These browser-based storage options serve various purposes and cater to different needs in web development.

    JavaScript Browser Storage
    @@ -107,6 +107,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which provides step-by-step instructions for setting up and using RxDB in your projects.
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/data-base.html b/docs/articles/data-base.html index 864606f882d..14b2f77601c 100644 --- a/docs/articles/data-base.html +++ b/docs/articles/data-base.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a data base: Empowering Web Applications with Reactive Data Handling

    +

    RxDB as a data base: Empowering Web Applications with Reactive Data Handling

    In the world of web applications, efficient data management plays a crucial role in delivering a seamless user experience. As mobile applications continue to dominate the digital landscape, the importance of robust data bases becomes evident. In this article, we will explore RxDB as a powerful data base solution for web applications. We will delve into its features, advantages, and advanced techniques, highlighting its ability to handle reactive data and enable an offline-first approach.

    Data Base

    Overview of Web Applications that can benefit from RxDB

    @@ -66,6 +66,6 @@

    JSON Ke

    In scenarios where storage size is a concern, RxDB provides JSON key compression. By applying compression techniques to JSON keys, developers can significantly reduce the storage footprint of their data bases. This feature is particularly beneficial for applications dealing with large datasets or limited storage capacities.

    Conclusion

    RxDB provides an exceptional data base solution for web and mobile applications, empowering developers to create reactive, offline-ready, and synchronized applications. With its reactive data handling, offline-first approach, and replication plugins, RxDB simplifies the challenges of building real-time applications with data synchronization requirements. By embracing advanced features like indexing, encryption, change streams, and JSON key compression, developers can optimize performance, enhance security, and reduce storage requirements. As web and mobile applications continue to evolve, RxDB proves to be a reliable and powerful

    -
    Data Base
    +
    Data Base
    \ No newline at end of file diff --git a/docs/articles/embedded-database.html b/docs/articles/embedded-database.html index 68f49c90f56..cb72d3b2a64 100644 --- a/docs/articles/embedded-database.html +++ b/docs/articles/embedded-database.html @@ -10,14 +10,14 @@ - - + + -

    Using RxDB as an Embedded Database

    +

    Using RxDB as an Embedded Database

    In modern UI applications, efficient data storage is a crucial aspect for seamless user experiences. One powerful solution for achieving this is by utilizing an embedded database. In this article, we will explore the concept of an embedded database and delve into the benefits of using RxDB as an embedded database in UI applications. We will also discuss why RxDB stands out as a robust choice for real-time applications with embedded database functionality.

    JavaScript Embedded Database

    What is an Embedded Database?

    @@ -59,6 +59,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which offers step-by-step instructions for setting up and using RxDB in your projects.
  • -

    By utilizing RxDB as an embedded database in UI applications, developers can harness the power of efficient data management, real-time updates, and enhanced user experiences. RxDB's features and benefits make it a compelling choice for building modern, responsive, and scalable applications.

    +

    By utilizing RxDB as an embedded database in UI applications, developers can harness the power of efficient data management, real-time updates, and enhanced user experiences. RxDB's features and benefits make it a compelling choice for building modern, responsive, and scalable applications.

    \ No newline at end of file diff --git a/docs/articles/firebase-realtime-database-alternative.html b/docs/articles/firebase-realtime-database-alternative.html index 4985c89f9e2..e770f870ec7 100644 --- a/docs/articles/firebase-realtime-database-alternative.html +++ b/docs/articles/firebase-realtime-database-alternative.html @@ -10,14 +10,14 @@ - - + + -

    RxDB - The Firebase Realtime Database Alternative That Can Sync With Your Own Backend

    +

    RxDB - The Firebase Realtime Database Alternative That Can Sync With Your Own Backend

    Are you on the lookout for a Firebase Realtime Database alternative that gives you greater freedom, deeper offline capabilities, and allows you to seamlessly integrate with any backend? RxDB (Reactive Database) might be the perfect choice. This local-first, NoSQL data store runs entirely on the client while supporting real-time updates and robust syncing with any server environment—making it a strong contender against Firebase Realtime Database's limitations and potential vendor lock-in.

    JavaScript Database

    Why RxDB Is an Excellent Firebase Realtime Database Alternative

    @@ -80,6 +80,6 @@

    queries locally, define indexing, and handle even complex transformations locally - no extra call to an external API.
  • Avoid Vendor Lock-In: If you anticipate needing to move or adapt your backend later, you can do so without rewriting how your client manages its data.
  • Peer-to-Peer Collaboration: Whether you need quick demos or real production use, WebRTC replication can link your users directly without central coordination of data storage.
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/firestore-alternative.html b/docs/articles/firestore-alternative.html index 372d2cfb5de..520d6afc0c7 100644 --- a/docs/articles/firestore-alternative.html +++ b/docs/articles/firestore-alternative.html @@ -10,14 +10,14 @@ - - + + -

    RxDB - The Firestore Alternative That Can Sync with Your Own Backend

    +
    +
    \ No newline at end of file diff --git a/docs/articles/flutter-database.html b/docs/articles/flutter-database.html index 93a9dcfd70a..1beb5ae0c59 100644 --- a/docs/articles/flutter-database.html +++ b/docs/articles/flutter-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a Database in a Flutter Application

    +

    RxDB as a Database in a Flutter Application

    In the world of mobile application development, Flutter has gained significant popularity due to its cross-platform capabilities and rich UI framework. When it comes to building feature-rich Flutter applications, the choice of a robust and efficient database is crucial. In this article, we will explore RxDB as a database solution for Flutter applications. We'll delve into the core features of RxDB, its benefits over other database options, and how to integrate it into a Flutter app.

    note

    You can find the source code for an example RxDB Flutter Application at the github repo

    RxDB Flutter Database
    @@ -82,6 +82,6 @@

    JSON Ke

    To minimize storage requirements and optimize performance, RxDB offers JSON key compression. This feature reduces the size of keys used in the database, resulting in more efficient storage and improved query performance.

    Conclusion

    RxDB offers a powerful and flexible database solution for Flutter applications. With its offline-first approach, real-time data synchronization, and reactive data handling capabilities, RxDB simplifies the development of feature-rich and scalable Flutter applications. By integrating RxDB into your Flutter projects, you can leverage its advanced features and techniques to build responsive and data-driven applications that provide an exceptional user experience.

    -
    note

    You can find the source code for an example RxDB Flutter Application at the github repo

    +
    note

    You can find the source code for an example RxDB Flutter Application at the github repo

    \ No newline at end of file diff --git a/docs/articles/frontend-database.html b/docs/articles/frontend-database.html index 9d8813c5d1a..15acd794847 100644 --- a/docs/articles/frontend-database.html +++ b/docs/articles/frontend-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB JavaScript Frontend Database: Efficient Data Storage in Frontend Applications

    +

    RxDB JavaScript Frontend Database: Efficient Data Storage in Frontend Applications

    In modern web development, managing data on the front end has become increasingly important. Storing data in the frontend offers numerous advantages, such as offline accessibility, caching, faster application startup, and improved state management. Traditional SQL databases, although widely used on the server-side, are not always the best fit for frontend applications. This is where RxDB, a frontend JavaScript database, emerges as a powerful solution. In this article, we will explore why storing data in the frontend is beneficial, the limitations of SQL databases in the frontend, and how RxDB addresses these challenges to become an excellent choice for frontend data storage.

    JavaScript Frontend Database

    Why you might want to store data in the frontend

    @@ -88,6 +88,6 @@

    Follow UpRxDB Quickstart: A step-by-step guide to quickly set up RxDB in your project and start leveraging its features.
  • RxDB GitHub Repository: The official repository for RxDB, where you can find the code, examples, and community support.
  • -

    By adopting RxDB as your frontend database, you can unlock the full potential of frontend data storage and empower your applications with offline accessibility, caching, improved performance, and seamless data synchronization. RxDB's JavaScript-centric approach and powerful features make it an ideal choice for frontend developers seeking efficient and scalable data storage solutions.

    +

    By adopting RxDB as your frontend database, you can unlock the full potential of frontend data storage and empower your applications with offline accessibility, caching, improved performance, and seamless data synchronization. RxDB's JavaScript-centric approach and powerful features make it an ideal choice for frontend developers seeking efficient and scalable data storage solutions.

    \ No newline at end of file diff --git a/docs/articles/ideas/index.html b/docs/articles/ideas/index.html index 7e21bf2d26d..9dea3ba7e52 100644 --- a/docs/articles/ideas/index.html +++ b/docs/articles/ideas/index.html @@ -10,14 +10,14 @@ - - + + -

    ideas for articles

    +
    +
    \ No newline at end of file diff --git a/docs/articles/in-memory-nosql-database.html b/docs/articles/in-memory-nosql-database.html index 58f0636ee88..3a186f8fa71 100644 --- a/docs/articles/in-memory-nosql-database.html +++ b/docs/articles/in-memory-nosql-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as In-memory NoSQL Database: Empowering Real-Time Applications

    +

    RxDB as In-memory NoSQL Database: Empowering Real-Time Applications

    Real-time applications have become increasingly popular in today's digital landscape. From instant messaging to collaborative editing tools, the demand for responsive and interactive software is on the rise. To meet these requirements, developers need powerful and efficient database solutions that can handle large amounts of data in real-time. RxDB, an javascript NoSQL database, is revolutionizing the way developers build and scale their applications by offering exceptional speed, flexibility, and scalability.

    RxDB Flutter Database

    Speed and Performance Benefits

    @@ -40,6 +40,6 @@

    Use Cases

    Real-Time Analytics Dashboards: RxDB's speed and scalability make it a valuable tool for real-time analytics dashboards. It can handle high volumes of data and perform complex analytics operations in real-time, providing instant insights and visualizations to users.

    -

    In conclusion, RxDB serves as a powerful in-memory NoSQL database that empowers developers to build real-time applications with exceptional speed, flexibility, and scalability. Its ability to leverage in-memory storage, eliminate disk I/O bottlenecks, and provide persistence options make it an attractive choice for a wide range of real-time use cases. Whether it's chat applications, collaborative document editors, or real-time analytics dashboards, RxDB provides the foundation for building responsive and interactive software that meets the demands of today's users.

    +

    In conclusion, RxDB serves as a powerful in-memory NoSQL database that empowers developers to build real-time applications with exceptional speed, flexibility, and scalability. Its ability to leverage in-memory storage, eliminate disk I/O bottlenecks, and provide persistence options make it an attractive choice for a wide range of real-time use cases. Whether it's chat applications, collaborative document editors, or real-time analytics dashboards, RxDB provides the foundation for building responsive and interactive software that meets the demands of today's users.

    \ No newline at end of file diff --git a/docs/articles/ionic-database.html b/docs/articles/ionic-database.html index 8ca3cb394f5..b75d1fa406d 100644 --- a/docs/articles/ionic-database.html +++ b/docs/articles/ionic-database.html @@ -10,14 +10,14 @@ - - + + -

    Ionic Storage - RxDB as database for hybrid apps

    +

    Ionic Storage - RxDB as database for hybrid apps

    In the fast-paced world of mobile app development, hybrid applications have emerged as a versatile solution, offering the best of both worlds - the web and native app experiences. One key challenge these apps face is efficiently storing and querying data on the client's device. Enter RxDB, a powerful client-side database tailored for ionic hybrid applications. In this article, we'll explore how RxDB addresses the requirements of storing and querying data in ionic apps, and why it stands out as a preferred choice.

    Ionic Database Storage

    What are Ionic Hybrid Apps?

    @@ -103,6 +103,6 @@

    Follow UpRxDB ionic example project
  • Try out the RxDB Quickstart
  • Join the RxDB Chat
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/ionic-storage.html b/docs/articles/ionic-storage.html index 42a4f90895f..18b1445bbe0 100644 --- a/docs/articles/ionic-storage.html +++ b/docs/articles/ionic-storage.html @@ -10,14 +10,14 @@ - - + + -

    RxDB - Local Ionic Storage with Encryption, Compression & Sync

    +

    RxDB - Local Ionic Storage with Encryption, Compression & Sync

    When building Ionic apps, developers face the challenge of choosing a robust Ionic storage mechanism that supports:

    -

    RxDB - The ultimate toolkit for Ionic developers seeking offline-first, secure, and compressed local data, with real-time sync to any server.

    +

    RxDB - The ultimate toolkit for Ionic developers seeking offline-first, secure, and compressed local data, with real-time sync to any server.

    \ No newline at end of file diff --git a/docs/articles/javascript-vector-database.html b/docs/articles/javascript-vector-database.html index 96371a387eb..b3b7ca65d76 100644 --- a/docs/articles/javascript-vector-database.html +++ b/docs/articles/javascript-vector-database.html @@ -10,14 +10,14 @@ - - + + -

    Local Vector Database with RxDB and transformers.js

    +

    Local Vector Database with RxDB and transformers.js

    The local-first revolution is here, changing the way we build apps! Imagine a world where your app's data lives right on the user's device, always available, even when there's no internet. That's the magic of local-first apps. Not only do they bring faster performance and limitless scalability, but they also empower users to work offline without missing a beat. And leading the charge in this space are local database solutions, like RxDB.

    JavaScript Database

    But here's where things get even more exciting: when building local-first apps, traditional databases often fall short. They're great at searching for exact matches, like numbers or strings, but what if you want to search by meaning, like sifting through emails to find a specific topic? Sure, you could use RegExp, but to truly unlock the power of semantic search and similarity-based queries, you need something more cutting-edge. Something that really understands the content of the data.

    @@ -182,6 +182,6 @@

    Follow Upat github
  • Learn how to use RxDB with the RxDB Quickstart
  • Check out the RxDB github repo and leave a star ⭐
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/jquery-database.html b/docs/articles/jquery-database.html index 9a1c6a36439..9e70b8c9df8 100644 --- a/docs/articles/jquery-database.html +++ b/docs/articles/jquery-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a Database in a jQuery Application

    +

    RxDB as a Database in a jQuery Application

    In the early days of dynamic web development, jQuery emerged as a popular library that simplified DOM manipulation and AJAX requests. Despite the rise of modern frameworks, many developers still maintain or extend existing jQuery projects, or leverage jQuery in specific contexts. As jQuery applications grow in complexity, they often require efficient data handling, offline support, and synchronization capabilities. This is where RxDB, a reactive JavaScript database for the browser, node.js, and mobile devices, steps in.

    JavaScript jQuery Database

    jQuery Web Applications

    @@ -111,6 +111,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which offers step-by-step instructions for setting up and using RxDB in your projects.
  • RxDB Examples: Browse official examples to see RxDB in action and learn best practices you can apply to your own project - even if jQuery isn't explicitly featured, the patterns are similar.
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/json-database.html b/docs/articles/json-database.html index b81c1bc16fb..18adfa69e54 100644 --- a/docs/articles/json-database.html +++ b/docs/articles/json-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB - JSON Database for JavaScript

    +

    RxDB - JSON Database for JavaScript

    Storing data as JSON documents in a NoSQL database is not just a trend; it's a practical choice. JSON data is highly compatible with various tools and is human-readable, making it an excellent fit for modern applications. JSON documents offer more flexibility compared to traditional SQL table rows, as they can contain nested data structures. This article introduces RxDB, an open-source, flexible, performant, and battle-tested NoSQL JSON database specifically designed for JavaScript applications.

    JSON Database

    Why Choose a JSON Database?

    @@ -95,6 +95,6 @@

    Follow UpRxDB Quickstart: A step-by-step guide to quickly set up RxDB in your project and start leveraging its features.
  • RxDB GitHub Repository: The official repository for RxDB, where you can find the code, examples, and community support.
  • -

    By embracing RxDB as your JSON database solution, you can tap into the extensive capabilities of JSON data storage. This empowers your applications with offline accessibility, caching, enhanced performance, and effortless data synchronization. RxDB's focus on JavaScript and its robust feature set render it the perfect selection for frontend developers in pursuit of efficient and scalable data storage solutions.

    +

    By embracing RxDB as your JSON database solution, you can tap into the extensive capabilities of JSON data storage. This empowers your applications with offline accessibility, caching, enhanced performance, and effortless data synchronization. RxDB's focus on JavaScript and its robust feature set render it the perfect selection for frontend developers in pursuit of efficient and scalable data storage solutions.

    \ No newline at end of file diff --git a/docs/articles/local-database.html b/docs/articles/local-database.html index 884190de39a..15b6c05ad44 100644 --- a/docs/articles/local-database.html +++ b/docs/articles/local-database.html @@ -10,14 +10,14 @@ - - + + -

    What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications

    +

    What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications

    A local database is a data storage system residing on a user's device, allowing applications to store, query, and manipulate information without needing continuous network access. This approach prioritizes quick data retrieval, efficient updates, and the ability to function in offline-first scenarios. In contrast, server-based databases require an active internet connection for each request and response cycle, making them more vulnerable to latency, network disruptions, and downtime.

    Local databases often leverage technologies such as IndexedDB, SQLite, or WebSQL (though WebSQL has been deprecated). These technologies manage both structured data (like relational tables) and unstructured data (such as JSON documents). When connectivity is restored, local databases typically sync their changes back to a central server-side database, maintaining consistent and up-to-date records across multiple devices.

    Use Cases of Local Databases

    @@ -94,6 +94,6 @@

    Follow UpQuickstart Tutorial and build a basic project to see RxDB in action.
  • Compare RxDB with other local database solutions to determine the best fit for your unique requirements.
  • -

    Ultimately, RxDB is more than just a database - it's a robust, reactive toolkit that empowers you to build fast, resilient, and user-centric applications. Whether you're creating an offline-first note-taking app or a real-time collaborative platform, RxDB can handle your local storage needs with ease and flexibility.

    +

    Ultimately, RxDB is more than just a database - it's a robust, reactive toolkit that empowers you to build fast, resilient, and user-centric applications. Whether you're creating an offline-first note-taking app or a real-time collaborative platform, RxDB can handle your local storage needs with ease and flexibility.

    \ No newline at end of file diff --git a/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html b/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html index 98672ec5532..67a2d56ec66 100644 --- a/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html +++ b/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html @@ -10,14 +10,14 @@ - - + + -

    LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite

    +

    LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite

    So you are building that web application and you want to store data inside of your users browser. Maybe you just need to store some small flags or you even need a fully fledged database.

    The types of web applications we build have changed significantly. In the early years of the web we served static html files. Then we served dynamically rendered html and later we build single page applications that run most logic on the client. And for the coming years you might want to build so called local first apps that handle big and complex data operations solely on the client and even work when offline, which gives you the opportunity to build zero-latency user interactions.

    In the early days of the web, cookies were the only option for storing small key-value assignments.. But JavaScript and browsers have evolved significantly and better storage APIs have been added which pave the way for bigger and more complex data operations.

    @@ -208,6 +208,6 @@

    Follow Upgithub repo
  • Learn how to use RxDB with the RxDB Quickstart
  • Check out the RxDB github repo and leave a star ⭐
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/localstorage.html b/docs/articles/localstorage.html index 9aba9eddfc8..ab4cbda11dc 100644 --- a/docs/articles/localstorage.html +++ b/docs/articles/localstorage.html @@ -10,14 +10,14 @@ - - + + -

    Using localStorage in Modern Applications: A Comprehensive Guide

    +

    Using localStorage in Modern Applications: A Comprehensive Guide

    When it comes to client-side storage in web applications, the localStorage API stands out as a simple and widely supported solution. It allows developers to store key-value pairs directly in a user's browser. In this article, we will explore the various aspects of the localStorage API, its advantages, limitations, and alternative storage options available for modern applications.

    JavaScript Database

    What is the localStorage API?

    @@ -85,6 +85,6 @@

    Follow upRxDB Quickstart
  • Why IndexedDB is slow and how to fix it
  • RxStorage performance comparison
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/mobile-database.html b/docs/articles/mobile-database.html index 0c7b611c02c..6cf099c38cf 100644 --- a/docs/articles/mobile-database.html +++ b/docs/articles/mobile-database.html @@ -10,14 +10,14 @@ - - + + -

    Mobile Database - RxDB as Database for Mobile Applications

    +

    Mobile Database - RxDB as Database for Mobile Applications

    In today's digital landscape, mobile applications have become an integral part of our lives. From social media platforms to e-commerce solutions, mobile apps have transformed the way we interact with digital services. At the heart of any mobile app lies the database, a critical component responsible for storing, retrieving, and managing data efficiently. In this article, we will delve into the world of mobile databases, exploring their significance, challenges, and the emergence of RxDB as a powerful database solution for hybrid app development in frameworks like React Native and Capacitor.

    Understanding Mobile Databases

    Mobile databases are specialized software systems designed to handle data storage and management for mobile applications. These databases are optimized for the unique requirements of mobile environments, which often include limited device resources, fluctuations in network connectivity, and the need for offline functionality.

    @@ -59,6 +59,6 @@

    Conclusion

    -

    Mobile databases play a vital role in the performance and functionality of mobile applications. RxDB, with its offline-first approach, real-time data synchronization, and seamless integration with hybrid app development frameworks like React Native and Capacitor, offers a robust solution for managing data in mobile apps. By leveraging the power of reactive programming, RxDB empowers developers to build highly responsive, scalable, and cross-platform applications that deliver an exceptional user experience. With its versatility and ease of use, RxDB is undoubtedly a database solution worth considering for hybrid app development. Embrace the power of RxDB and unlock the full potential of your mobile applications.

    +

    Mobile databases play a vital role in the performance and functionality of mobile applications. RxDB, with its offline-first approach, real-time data synchronization, and seamless integration with hybrid app development frameworks like React Native and Capacitor, offers a robust solution for managing data in mobile apps. By leveraging the power of reactive programming, RxDB empowers developers to build highly responsive, scalable, and cross-platform applications that deliver an exceptional user experience. With its versatility and ease of use, RxDB is undoubtedly a database solution worth considering for hybrid app development. Embrace the power of RxDB and unlock the full potential of your mobile applications.

    \ No newline at end of file diff --git a/docs/articles/offline-database.html b/docs/articles/offline-database.html index 8c84e5244d7..641b3bbc49d 100644 --- a/docs/articles/offline-database.html +++ b/docs/articles/offline-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB – The Ultimate Offline Database with Sync and Encryption

    +

    RxDB – The Ultimate Offline Database with Sync and Encryption

    When building modern applications, a reliable offline database can make all the difference. Users need fast, uninterrupted access to data, even without an internet connection, and they need that data to stay secure. RxDB meets these requirements by providing a local-first architecture, real-time sync to any backend, and optional encryption for sensitive fields.

    In this article, we'll cover:

    -

    By adopting an offline database approach with RxDB, you unlock speed, reliability, and security for your applications—leading to a truly seamless user experience.

    +

    By adopting an offline database approach with RxDB, you unlock speed, reliability, and security for your applications—leading to a truly seamless user experience.

    \ No newline at end of file diff --git a/docs/articles/optimistic-ui.html b/docs/articles/optimistic-ui.html index 27731da32f3..1dc87a1f31c 100644 --- a/docs/articles/optimistic-ui.html +++ b/docs/articles/optimistic-ui.html @@ -10,14 +10,14 @@ - - + + -

    Building an Optimistic UI with RxDB

    +

    Building an Optimistic UI with RxDB

    An Optimistic User Interface (UI) is a design pattern that provides instant feedback to the user by assuming that an operation or server call will succeed. Instead of showing loading spinners or waiting for server confirmations, the UI immediately reflects the user's intended action and later reconciles the displayed data with the actual server response. This approach drastically improves perceived performance and user satisfaction.

    Benefits of an Optimistic UI

    Optimistic UIs offer a host of advantages, from improving the user experience to streamlining the underlying infrastructure. Below are some key reasons why an optimistic approach can revolutionize your application's performance and scalability.

    @@ -162,6 +162,6 @@

    Follow UpRxDB GitHub Repository.

    -

    By combining RxDB's powerful offline-first capabilities with the principles of an Optimistic UI, you can deliver snappy, near-instant user interactions that keep your users engaged - no matter the network conditions. Get started today and give your users the experience they deserve!

    +

    By combining RxDB's powerful offline-first capabilities with the principles of an Optimistic UI, you can deliver snappy, near-instant user interactions that keep your users engaged - no matter the network conditions. Get started today and give your users the experience they deserve!

    \ No newline at end of file diff --git a/docs/articles/progressive-web-app-database.html b/docs/articles/progressive-web-app-database.html index 11633cd06f1..9ca52a6cddf 100644 --- a/docs/articles/progressive-web-app-database.html +++ b/docs/articles/progressive-web-app-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a Database for Progressive Web Apps (PWA)

    +

    RxDB as a Database for Progressive Web Apps (PWA)

    Progressive Web Apps (PWAs) have revolutionized the digital landscape, offering users an immersive blend of web and native app experiences. At the heart of every successful PWA lies effective data management, and this is where RxDB comes into play. In this article, we'll explore the dynamic synergy between RxDB, a robust client-side database, and Progressive Web Apps, uncovering how RxDB enhances data handling, synchronization, and overall performance, propelling PWAs into a new era of excellence.

    What is a Progressive Web App

    Progressive Web Apps are the future of web development, seamlessly combining the best of both web and mobile app worlds. They can be easily installed on the user's home screen, function offline, and load at lightning speed. Unlike hybrid apps, PWAs offer a consistent user experience across platforms, making them a versatile choice for modern applications.

    @@ -79,6 +79,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which provides step-by-step instructions for setting up and using RxDB in your projects.
  • RxDB Progressive Web App in Angular Example
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/react-database.html b/docs/articles/react-database.html index 762dc6248e4..ca5605d1151 100644 --- a/docs/articles/react-database.html +++ b/docs/articles/react-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a Database for React Applications

    +

    RxDB as a Database for React Applications

    In the rapidly evolving landscape of web development, React has emerged as a cornerstone technology for building dynamic and responsive user interfaces. With the increasing complexity of modern web applications, efficient data management becomes pivotal. This article delves into the integration of RxDB, a potent client-side database, with React applications to optimize data handling and elevate the overall user experience.

    React has revolutionized the way web applications are built by introducing a component-based architecture. This approach enables developers to create reusable UI components that efficiently update in response to changes in data. The virtual DOM mechanism, a key feature of React, facilitates optimized rendering, enhancing performance and user interactivity.

    While React excels at managing the user interface, the need for efficient data storage and retrieval mechanisms is equally significant. A client-side database brings several advantages to React applications:

    @@ -86,6 +86,6 @@

    Follow UpRxDB GitHub Repository: Visit the official GitHub repository of RxDB to access the source code, documentation, and community support.
  • RxDB Quickstart: Get started quickly with RxDB by following the provided quickstart guide, which provides step-by-step instructions for setting up and using RxDB in your projects.
  • RxDB React Example at GitHub
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/react-indexeddb.html b/docs/articles/react-indexeddb.html index 675a60848a3..6ac35b526a1 100644 --- a/docs/articles/react-indexeddb.html +++ b/docs/articles/react-indexeddb.html @@ -10,14 +10,14 @@ - - + + -

    IndexedDB Database in React Apps - The Power of RxDB

    +

    IndexedDB Database in React Apps - The Power of RxDB

    Building robust, offline-capable React applications often involves leveraging browser storage solutions to manage data. IndexedDB is one such powerful tool, but its raw API can be challenging to work with directly. RxDB abstracts away much of IndexedDB's complexity, providing a more developer-friendly experience. In this article, we'll explore what IndexedDB is, why it's beneficial in React applications, the challenges of using plain IndexedDB, and how RxDB can simplify your development process while adding advanced features.

    What is IndexedDB?

    IndexedDB is a low-level API for storing significant amounts of structured data in the browser. It provides a transactional database system that can store key-value pairs, complex objects, and more. This storage engine is asynchronous and supports advanced data types, making it suitable for offline storage and complex web applications.

    @@ -105,6 +105,6 @@

    Follow UpRxDB Quickstart for a guided introduction.
  • Check out the RxDB GitHub repository and leave a star ⭐ if you find it useful.
  • -

    By leveraging RxDB on top of IndexedDB, you can create highly responsive, offline-capable React applications without dealing with the low-level complexities of IndexedDB directly. With reactive queries, seamless cross-tab communication, and powerful advanced features, RxDB becomes an invaluable tool in modern web development.

    +

    By leveraging RxDB on top of IndexedDB, you can create highly responsive, offline-capable React applications without dealing with the low-level complexities of IndexedDB directly. With reactive queries, seamless cross-tab communication, and powerful advanced features, RxDB becomes an invaluable tool in modern web development.

    \ No newline at end of file diff --git a/docs/articles/react-native-encryption.html b/docs/articles/react-native-encryption.html index 5c3e3fe6d9f..c8fdbe3c80b 100644 --- a/docs/articles/react-native-encryption.html +++ b/docs/articles/react-native-encryption.html @@ -10,14 +10,14 @@ - - + + -

    React Native Encryption and Encrypted Database/Storage

    +

    React Native Encryption and Encrypted Database/Storage

    Data security is a critical concern in modern mobile applications. As React Native continues to grow in popularity for building cross-platform apps, ensuring that your data is protected is paramount. RxDB, a real-time database for JavaScript applications, offers powerful encryption features that can help you secure your React Native app's data.

    This article explains why encryption is important, how to set it up with RxDB in React Native, and best practices to keep your app secure.

    🔒 Why Encryption Matters

    @@ -99,6 +99,6 @@

    Follow UpRxDB GitHub repository and leave a star ⭐ if you find it useful.
  • Learn more about the RxDB encryption plugins.
  • -

    By following these best practices and leveraging RxDB's powerful encryption plugins, you can build secure, performant, and robust React Native applications that keep your users' data safe.

    +

    By following these best practices and leveraging RxDB's powerful encryption plugins, you can build secure, performant, and robust React Native applications that keep your users' data safe.

    \ No newline at end of file diff --git a/docs/articles/realtime-database.html b/docs/articles/realtime-database.html index 2054f75e955..6693084afe2 100644 --- a/docs/articles/realtime-database.html +++ b/docs/articles/realtime-database.html @@ -10,14 +10,14 @@ - - + + -

    What is a realtime database?

    +

    What is a realtime database?

    I have been building RxDB, a NoSQL realtime JavaScript database for many years. Often people get confused by the word realtime database, because the word realtime is so vaguely defined that it can mean everything and nothing at the same time.

    In this article we will explore what a realtime database is, and more important, what it is not.

    @@ -45,6 +45,6 @@

    Follow UpRxDB Quickstart
  • Discover more about the RxDB realtime replication protocol
  • Join the conversation at RxDB Chat
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/vue-database.html b/docs/articles/vue-database.html index ab83b4119fb..1212d4fa64d 100644 --- a/docs/articles/vue-database.html +++ b/docs/articles/vue-database.html @@ -10,14 +10,14 @@ - - + + -

    RxDB as a Database in a Vue Application

    +

    RxDB as a Database in a Vue Application

    In the modern web ecosystem, Vue has become a leading choice for building highly performant, reactive single-page applications (SPAs). However, while Vue excels at managing and updating the user interface, robust and efficient data handling also plays a pivotal role in delivering a great user experience. Enter RxDB, a reactive JavaScript database that runs in the browser (and beyond), offering significant capabilities such as offline-first data handling, real-time synchronization, and straightforward integration with Vue's reactivity system.

    This article explores how RxDB works, why it's a perfect match for Vue, and how you can leverage it to build more engaging, performant, and data-resilient Vue applications.

    JavaScript Vue Database
    @@ -104,6 +104,6 @@

    Follow UpRxDB Reactivity for Vue: Discover how RxDB observables can directly produce Vue refs, simplifying integration with your Vue components.
  • RxDB Vue Example at GitHub: Explore an official Vue example to see RxDB in action within a Vue application.
  • RxDB Examples: Browse even more official examples to learn best practices you can apply to your own projects.
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/vue-indexeddb.html b/docs/articles/vue-indexeddb.html index bf9c63aab2b..a2d5c5b43a3 100644 --- a/docs/articles/vue-indexeddb.html +++ b/docs/articles/vue-indexeddb.html @@ -10,14 +10,14 @@ - - + + -

    IndexedDB Database in Vue Apps - The Power of RxDB

    +

    IndexedDB Database in Vue Apps - The Power of RxDB

    Building robust, offline-capable Vue applications often involves leveraging browser storage solutions to manage data. IndexedDB is one such powerful tool, but its raw API can be challenging to work with directly. RxDB abstracts away much of IndexedDB's complexity, providing a more developer-friendly experience. In this article, we'll explore what IndexedDB is, why it's beneficial in Vue applications, the challenges of using plain IndexedDB, and how RxDB can simplify your development process while adding advanced features.

    What is IndexedDB?

    IndexedDB is a low-level API for storing significant amounts of structured data in the browser. It provides a transactional database system that can store key-value pairs, complex objects, and more. This storage engine is asynchronous and supports advanced data types, making it suitable for offline storage and complex web applications.

    @@ -109,6 +109,6 @@

    Follow UpRxDB Quickstart for a guided introduction.
  • Check out the RxDB GitHub repository and leave a star ⭐ if you find it useful.
  • -

    By leveraging RxDB on top of IndexedDB, you can create highly responsive, offline-capable Vue applications without dealing with the low-level complexities of IndexedDB directly. With reactive queries, seamless cross-tab communication, and powerful advanced features, RxDB becomes an invaluable tool in modern web development.

    +

    By leveraging RxDB on top of IndexedDB, you can create highly responsive, offline-capable Vue applications without dealing with the low-level complexities of IndexedDB directly. With reactive queries, seamless cross-tab communication, and powerful advanced features, RxDB becomes an invaluable tool in modern web development.

    \ No newline at end of file diff --git a/docs/articles/websockets-sse-polling-webrtc-webtransport.html b/docs/articles/websockets-sse-polling-webrtc-webtransport.html index 9f05013cc2b..816d63b07a4 100644 --- a/docs/articles/websockets-sse-polling-webrtc-webtransport.html +++ b/docs/articles/websockets-sse-polling-webrtc-webtransport.html @@ -10,14 +10,14 @@ - - + + -

    WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport

    +

    WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport

    For modern real-time web applications, the ability to send events from the server to the client is indispensable. This necessity has led to the development of several methods over the years, each with its own set of advantages and drawbacks. Initially, long-polling was the only option available. It was then succeeded by WebSockets, which offered a more robust solution for bidirectional communication. Following WebSockets, Server-Sent Events (SSE) provided a simpler method for one-way communication from server to client. Looking ahead, the WebTransport protocol promises to revolutionize this landscape even further by providing a more efficient, flexible, and scalable approach. For niche use cases, WebRTC might also be considered for server-client events.

    This article aims to delve into these technologies, comparing their performance, highlighting their benefits and limitations, and offering recommendations for various use cases to help developers make informed decisions when building real-time web applications. It is a condensed summary of my gathered experience when I implemented the RxDB Replication Protocol to be compatible with various backend technologies.

    JavaScript Database
    @@ -117,6 +117,6 @@

    Follow Upreplicate a client side RxDB database with your backend.
  • Learn how to use RxDB with the RxDB Quickstart
  • Check out the RxDB github repo and leave a star ⭐
  • -

    +
    \ No newline at end of file diff --git a/docs/articles/zero-latency-local-first.html b/docs/articles/zero-latency-local-first.html index 592218503da..9ce4f4eb36d 100644 --- a/docs/articles/zero-latency-local-first.html +++ b/docs/articles/zero-latency-local-first.html @@ -10,14 +10,14 @@ - - + + -

    Zero Latency Local First Apps with RxDB – Sync, Encryption and Compression

    +

    Zero Latency Local First Apps with RxDB – Sync, Encryption and Compression

    Creating a zero-latency local first application involves ensuring that most (if not all) user interactions occur instantaneously, without waiting on remote network responses. This design drastically enhances user experience, allowing apps to remain responsive and functional even when offline or experiencing poor connectivity. As developers, we can achieve this by storing data locally on the client and synchronizing it to the backend in the background. RxDB (Reactive Database) offers a comprehensive set of features - covering replication, offline support, encryption, compression, conflict handling, and more - that make it straightforward to build such high-performing apps.

    loading spinner not needed

    Why Zero Latency with a Local First Approach?

    @@ -93,6 +93,6 @@

    Follow UpGitHub and Discord to share insights, file issues, and learn from other developers building zero-latency solutions.
  • -

    By integrating RxDB into your stack, you achieve millisecond interactions, full offline capabilities, secure data at rest, and minimal overhead for large or distributed teams. This zero-latency local first architecture is the future of modern software - delivering a fluid, always-available user experience without overcomplicating the developer workflow.

    +

    By integrating RxDB into your stack, you achieve millisecond interactions, full offline capabilities, secure data at rest, and minimal overhead for large or distributed teams. This zero-latency local first architecture is the future of modern software - delivering a fluid, always-available user experience without overcomplicating the developer workflow.

    \ No newline at end of file diff --git a/docs/assets/js/045bd6f5.abd6640e.js b/docs/assets/js/045bd6f5.abd6640e.js deleted file mode 100644 index a690a9f176a..00000000000 --- a/docs/assets/js/045bd6f5.abd6640e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4475],{6621:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"encryption","title":"Encryption","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage.","source":"@site/docs/encryption.md","sourceDirName":".","slug":"/encryption.html","permalink":"/encryption.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Encryption","slug":"encryption.html","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage."},"sidebar":"tutorialSidebar","previous":{"title":"Schema Validation","permalink":"/schema-validation.html"},"next":{"title":"Key Compression","permalink":"/key-compression.html"}}');var a=t(4848),s=t(8453);const o={title:"Encryption",slug:"encryption.html",description:"Explore RxDB's \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage."},i="\ud83d\udd12 Encrypted Local Storage with RxDB",d={},c=[{value:"Querying encrypted data",id:"querying-encrypted-data",level:2},{value:"Password handling",id:"password-handling",level:2},{value:"Asymmetric encryption",id:"asymmetric-encryption",level:2},{value:"Using the RxDB Encryption Plugins",id:"using-the-rxdb-encryption-plugins",level:2},{value:"Changing the password",id:"changing-the-password",level:2},{value:"Encrypted attachments",id:"encrypted-attachments",level:2},{value:"Encryption and workers",id:"encryption-and-workers",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"-encrypted-local-storage-with-rxdb",children:"\ud83d\udd12 Encrypted Local Storage with RxDB"})}),"\n",(0,a.jsxs)(n.p,{children:["The RxDB encryption plugin empowers developers to fortify their applications' data security. It seamlessly integrates with ",(0,a.jsx)(n.a,{href:"https://rxdb.info/",children:"RxDB"}),", allowing for the secure storage and retrieval of documents by ",(0,a.jsx)(n.strong,{children:"encrypting them with a password"}),". With encryption and decryption processes handled internally, it ensures that sensitive data remains confidential, making it a valuable tool for building robust, privacy-conscious applications. The encryption works on all RxDB supported devices types like the ",(0,a.jsx)(n.strong,{children:"browser"}),", ",(0,a.jsx)(n.strong,{children:"ReactNative"})," or ",(0,a.jsx)(n.strong,{children:"Node.js"}),"."]}),"\n",(0,a.jsx)("p",{align:"center",children:(0,a.jsx)("img",{src:"./files/icons/with-gradient/storage-layer.svg",alt:"Encryption Storage Layer",height:"60"})}),"\n",(0,a.jsx)(n.p,{children:"Encrypting client-side stored data in RxDB offers numerous advantages:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Enhanced Security"}),": In the unfortunate event of a user's device being stolen, the encrypted data remains safeguarded on the hard drive, inaccessible without the correct password."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Access Control"}),": You can retain control over stored data by revoking access at any time simply by withholding the password."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Tamper proof"})," Other applications on the device cannot read out the stored data when the password is only kept in the process-specific memory"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-encrypted-data",children:"Querying encrypted data"}),"\n",(0,a.jsxs)(n.p,{children:["RxDB handles the encryption and decryption of data internally. This means that when you work with a RxDocument, you can access the properties of the document just like you would with normal, unencrypted data. RxDB automatically decrypts the data for you when you retrieve it, making it transparent to your application code.\nThis means the encryption works with all ",(0,a.jsx)(n.a,{href:"/rx-storage.html",children:"RxStorage"})," like ",(0,a.jsx)(n.strong,{children:"SQLite"}),", ",(0,a.jsx)(n.strong,{children:"IndexedDB"}),", ",(0,a.jsx)(n.strong,{children:"OPFS"})," and so on."]}),"\n",(0,a.jsxs)(n.p,{children:["However, there's a limitation when it comes to querying encrypted fields. ",(0,a.jsx)(n.strong,{children:"Encrypted fields cannot be used as operators in queries"}),'. This means you cannot perform queries like "find all documents where the encrypted field equals a certain value." RxDB does not expose the encrypted data in a way that allows direct querying based on the encrypted content. To filter or search for documents based on the contents of encrypted fields, you would need to first decrypt the data and then perform the query, which might not be efficient or practical in some cases.\nYou could however use the ',(0,a.jsx)(n.a,{href:"/rx-storage-memory-mapped.html",children:"memory mapped"})," RxStorage to replicate the encrypted documents into a non-encrypted in-memory storage and then query them like normal."]}),"\n",(0,a.jsx)(n.h2,{id:"password-handling",children:"Password handling"}),"\n",(0,a.jsx)(n.p,{children:"RxDB does not define how you should store or retrieve the encryption password. It only requires you to provide the password on database creation which grants you flexibility in how you manage encryption passwords.\nYou could ask the user on app-start to insert the password, or you can retrieve the password from your backend on app start (or revoke access by no longer providing the password)."}),"\n",(0,a.jsx)(n.h2,{id:"asymmetric-encryption",children:"Asymmetric encryption"}),"\n",(0,a.jsxs)(n.p,{children:["The encryption plugin itself uses ",(0,a.jsx)(n.strong,{children:"symmetric encryption"})," with a password to guarantee best performance when reading and storing data.\nIt is not able to do ",(0,a.jsx)(n.strong,{children:"Asymmetric encryption"})," by itself. If you need Asymmetric encryption with a private/publicKey, it is recommended to encrypted the password itself with the asymentric keys and store the encrypted password beside the other data. On app-start you can decrypt the password with the private key and use the decrypted password in the RxDB encryption plugin"]}),"\n",(0,a.jsx)(n.h2,{id:"using-the-rxdb-encryption-plugins",children:"Using the RxDB Encryption Plugins"}),"\n",(0,a.jsx)(n.p,{children:"RxDB currently has two plugins for encryption:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["The free ",(0,a.jsx)(n.code,{children:"encryption-crypto-js"})," plugin that is based on the ",(0,a.jsx)(n.code,{children:"AES"})," algorithm of the ",(0,a.jsx)(n.a,{href:"https://www.npmjs.com/package/crypto-js",children:"crypto-js"})," library"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.a,{href:"/premium/",children:"\ud83d\udc51 premium"})," ",(0,a.jsx)(n.code,{children:"encryption-web-crypto"})," plugin that is based on the native ",(0,a.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API",children:"Web Crypto API"})," which makes it faster and more secure to use. Document inserts are about 10x faster compared to ",(0,a.jsx)(n.code,{children:"crypto-js"})," and it has a smaller build size because it uses the browsers API instead of bundling an npm module."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["An RxDB encryption plugin is a wrapper around any other ",(0,a.jsx)(n.a,{href:"/rx-storage.html",children:"RxStorage"}),"."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You first have to wrap your RxStorage with the encryption"}),"\n",(0,a.jsxs)(n.li,{children:["Then use that as ",(0,a.jsx)(n.code,{children:"RxStorage"})," when calling ",(0,a.jsx)(n.code,{children:"createRxDatabase()"})]}),"\n",(0,a.jsxs)(n.li,{children:["Also you have to set a ",(0,a.jsx)(n.strong,{children:"password"})," when creating the database. The format of the password depends on which encryption plugin is used."]}),"\n",(0,a.jsxs)(n.li,{children:["To define a field as being encrypted, you have to add it to the ",(0,a.jsx)(n.code,{children:"encrypted"})," fields list in the schema."]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"import { wrappedKeyEncryptionCryptoJsStorage } from 'rxdb/plugins/encryption-crypto-js';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\n\n// wrap the normal storage with the encryption plugin\nconst encryptedDexieStorage = wrappedKeyEncryptionCryptoJsStorage({\n storage: getRxStorageDexie()\n});\n\n// create an encrypted database\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: encryptedDexieStorage,\n password: 'sudoLetMeIn'\n});\n\n\nconst schema = {\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100\n },\n secret: {\n type: 'string'\n },\n },\n required: ['id']\n encrypted: ['secret']\n};\n\nawait db.addCollections({\n myDocuments: {\n schema\n }\n})\n/* ... */\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Or with the ",(0,a.jsx)(n.code,{children:"web-crypto"})," ",(0,a.jsx)(n.a,{href:"/premium/",children:"\ud83d\udc51 premium"})," plugin:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"import {\n wrappedKeyEncryptionWebCryptoStorage,\n createPassword\n} from 'rxdb-premium/plugins/encryption-web-crypto';\nimport { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';\n\n// wrap the normal storage with the encryption plugin\nconst encryptedIndexedDbStorage = wrappedKeyEncryptionWebCryptoStorage({\n storage: getRxStorageIndexedDB()\n});\n\nconst myPasswordObject = {\n // Algorithm can be oneOf: 'AES-CTR' | 'AES-CBC' | 'AES-GCM'\n algorithm: 'AES-CTR',\n password: 'myRandomPasswordWithMin8Length'\n};\n\n// create an encrypted database\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: encryptedIndexedDbStorage,\n password: myPasswordObject\n});\n\n/* ... */\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changing-the-password",children:"Changing the password"}),"\n",(0,a.jsx)(n.p,{children:"The password is set database specific and it is not possible to change the password of a database. Opening an existing database with a different password will throw an error. To change the password you can either:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Use the ",(0,a.jsx)(n.a,{href:"/migration-storage.html",children:"storage migration plugin"})," to migrate the database state into a new database."]}),"\n",(0,a.jsxs)(n.li,{children:["Store a randomly created meta-password in a different RxDatabase as a value of a ",(0,a.jsx)(n.a,{href:"/rx-local-document.html",children:"local document"}),". Encrypt the meta password with the actual user password and read it out before creating the actual database."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"encrypted-attachments",children:"Encrypted attachments"}),"\n",(0,a.jsxs)(n.p,{children:["To store the ",(0,a.jsx)(n.a,{href:"/rx-attachment.html",children:"attachments"})," data encrypted, you have to set ",(0,a.jsx)(n.code,{children:"encrypted: true"})," in the ",(0,a.jsx)(n.code,{children:"attachments"})," property of the schema."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"const mySchema = {\n version: 0,\n type: 'object',\n properties: {\n /* ... */\n },\n attachments: {\n encrypted: true // if true, the attachment-data will be encrypted with the db-password\n }\n};\n"})}),"\n",(0,a.jsx)(n.h2,{id:"encryption-and-workers",children:"Encryption and workers"}),"\n",(0,a.jsxs)(n.p,{children:["If you are using ",(0,a.jsx)(n.a,{href:"/rx-storage-worker.html",children:"Worker RxStorage"})," or ",(0,a.jsx)(n.a,{href:"/rx-storage-shared-worker.html",children:"SharedWorker RxStorage"})," with encryption, it's recommended to run encryption inside of the worker. Encryption can be very cpu intensive and would take away CPU-power from the main thread which is the main reason to use workers."]}),"\n",(0,a.jsx)(n.p,{children:"You do not need to worry about setting the password inside of the worker. The password will be set when calling createRxDatabase from the main thread, and will be passed internally to the storage in the worker automatically."})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var r=t(6540);const a={},s=r.createContext(a);function o(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/045bd6f5.f6ff261c.js b/docs/assets/js/045bd6f5.f6ff261c.js new file mode 100644 index 00000000000..39dbe6c4e74 --- /dev/null +++ b/docs/assets/js/045bd6f5.f6ff261c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4475],{6621:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>p});const r=JSON.parse('{"id":"encryption","title":"Encryption","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage.","source":"@site/docs/encryption.md","sourceDirName":".","slug":"/encryption.html","permalink":"/encryption.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Encryption","slug":"encryption.html","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage."},"sidebar":"tutorialSidebar","previous":{"title":"Schema Validation","permalink":"/schema-validation.html"},"next":{"title":"Key Compression","permalink":"/key-compression.html"}}');var a=n(4848),s=n(8453),i=n(7580);const o={title:"Encryption",slug:"encryption.html",description:"Explore RxDB's \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage."},d="\ud83d\udd12 Encrypted Local Storage with RxDB",c={},p=[{value:"Querying encrypted data",id:"querying-encrypted-data",level:2},{value:"Password handling",id:"password-handling",level:2},{value:"Asymmetric encryption",id:"asymmetric-encryption",level:2},{value:"Using the RxDB Encryption Plugins",id:"using-the-rxdb-encryption-plugins",level:2},{value:"Wrap your RxStorage with the encryption",id:"wrap-your-rxstorage-with-the-encryption",level:3},{value:"Create a RxDatabase with the wrapped storage",id:"create-a-rxdatabase-with-the-wrapped-storage",level:3},{value:"Create an RxCollection with an encrypted property",id:"create-an-rxcollection-with-an-encrypted-property",level:3},{value:"Using Web-Crypto API",id:"using-web-crypto-api",level:2},{value:"Changing the password",id:"changing-the-password",level:2},{value:"Encrypted attachments",id:"encrypted-attachments",level:2},{value:"Encryption and workers",id:"encryption-and-workers",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"-encrypted-local-storage-with-rxdb",children:"\ud83d\udd12 Encrypted Local Storage with RxDB"})}),"\n",(0,a.jsxs)(t.p,{children:["The RxDB encryption plugin empowers developers to fortify their applications' data security. It seamlessly integrates with ",(0,a.jsx)(t.a,{href:"https://rxdb.info/",children:"RxDB"}),", allowing for the secure storage and retrieval of documents by ",(0,a.jsx)(t.strong,{children:"encrypting them with a password"}),". With encryption and decryption processes handled internally, it ensures that sensitive data remains confidential, making it a valuable tool for building robust, privacy-conscious applications. The encryption works on all RxDB supported devices types like the ",(0,a.jsx)(t.strong,{children:"browser"}),", ",(0,a.jsx)(t.strong,{children:"ReactNative"})," or ",(0,a.jsx)(t.strong,{children:"Node.js"}),"."]}),"\n",(0,a.jsx)("p",{align:"center",children:(0,a.jsx)("img",{src:"./files/icons/with-gradient/storage-layer.svg",alt:"Encryption Storage Layer",height:"60"})}),"\n",(0,a.jsx)(t.p,{children:"Encrypting client-side stored data in RxDB offers numerous advantages:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Enhanced Security"}),": In the unfortunate event of a user's device being stolen, the encrypted data remains safeguarded on the hard drive, inaccessible without the correct password."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Access Control"}),": You can retain control over stored data by revoking access at any time simply by withholding the password."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Tamper proof"})," Other applications on the device cannot read out the stored data when the password is only kept in the process-specific memory"]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"querying-encrypted-data",children:"Querying encrypted data"}),"\n",(0,a.jsxs)(t.p,{children:["RxDB handles the encryption and decryption of data internally. This means that when you work with a RxDocument, you can access the properties of the document just like you would with normal, unencrypted data. RxDB automatically decrypts the data for you when you retrieve it, making it transparent to your application code.\nThis means the encryption works with all ",(0,a.jsx)(t.a,{href:"/rx-storage.html",children:"RxStorage"})," like ",(0,a.jsx)(t.strong,{children:"SQLite"}),", ",(0,a.jsx)(t.strong,{children:"IndexedDB"}),", ",(0,a.jsx)(t.strong,{children:"OPFS"})," and so on."]}),"\n",(0,a.jsxs)(t.p,{children:["However, there's a limitation when it comes to querying encrypted fields. ",(0,a.jsx)(t.strong,{children:"Encrypted fields cannot be used as operators in queries"}),'. This means you cannot perform queries like "find all documents where the encrypted field equals a certain value." RxDB does not expose the encrypted data in a way that allows direct querying based on the encrypted content. To filter or search for documents based on the contents of encrypted fields, you would need to first decrypt the data and then perform the query, which might not be efficient or practical in some cases.\nYou could however use the ',(0,a.jsx)(t.a,{href:"/rx-storage-memory-mapped.html",children:"memory mapped"})," RxStorage to replicate the encrypted documents into a non-encrypted in-memory storage and then query them like normal."]}),"\n",(0,a.jsx)(t.h2,{id:"password-handling",children:"Password handling"}),"\n",(0,a.jsx)(t.p,{children:"RxDB does not define how you should store or retrieve the encryption password. It only requires you to provide the password on database creation which grants you flexibility in how you manage encryption passwords.\nYou could ask the user on app-start to insert the password, or you can retrieve the password from your backend on app start (or revoke access by no longer providing the password)."}),"\n",(0,a.jsx)(t.h2,{id:"asymmetric-encryption",children:"Asymmetric encryption"}),"\n",(0,a.jsxs)(t.p,{children:["The encryption plugin itself uses ",(0,a.jsx)(t.strong,{children:"symmetric encryption"})," with a password to guarantee best performance when reading and storing data.\nIt is not able to do ",(0,a.jsx)(t.strong,{children:"Asymmetric encryption"})," by itself. If you need Asymmetric encryption with a private/publicKey, it is recommended to encrypted the password itself with the asymentric keys and store the encrypted password beside the other data. On app-start you can decrypt the password with the private key and use the decrypted password in the RxDB encryption plugin"]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-rxdb-encryption-plugins",children:"Using the RxDB Encryption Plugins"}),"\n",(0,a.jsx)(t.p,{children:"RxDB currently has two plugins for encryption:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["The free ",(0,a.jsx)(t.code,{children:"encryption-crypto-js"})," plugin that is based on the ",(0,a.jsx)(t.code,{children:"AES"})," algorithm of the ",(0,a.jsx)(t.a,{href:"https://www.npmjs.com/package/crypto-js",children:"crypto-js"})," library"]}),"\n",(0,a.jsxs)(t.li,{children:["The ",(0,a.jsx)(t.a,{href:"/premium/",children:"\ud83d\udc51 premium"})," ",(0,a.jsx)(t.code,{children:"encryption-web-crypto"})," plugin that is based on the native ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API",children:"Web Crypto API"})," which makes it faster and more secure to use. Document inserts are about 10x faster compared to ",(0,a.jsx)(t.code,{children:"crypto-js"})," and it has a smaller build size because it uses the browsers API instead of bundling an npm module."]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["An RxDB encryption plugin is a wrapper around any other ",(0,a.jsx)(t.a,{href:"/rx-storage.html",children:"RxStorage"}),"."]}),"\n",(0,a.jsxs)(i.g,{children:[(0,a.jsx)(t.h3,{id:"wrap-your-rxstorage-with-the-encryption",children:"Wrap your RxStorage with the encryption"}),(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-ts",children:"import {\n wrappedKeyEncryptionCryptoJsStorage\n} from 'rxdb/plugins/encryption-crypto-js';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\n// wrap the normal storage with the encryption plugin\nconst encryptedDexieStorage = wrappedKeyEncryptionCryptoJsStorage({\n storage: getRxStorageDexie()\n});\n"})}),(0,a.jsx)(t.h3,{id:"create-a-rxdatabase-with-the-wrapped-storage",children:"Create a RxDatabase with the wrapped storage"}),(0,a.jsxs)(t.p,{children:["Also you have to set a ",(0,a.jsx)(t.strong,{children:"password"})," when creating the database. The format of the password depends on which encryption plugin is used."]}),(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\n// create an encrypted database\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: encryptedDexieStorage,\n password: 'sudoLetMeIn'\n});\n"})}),(0,a.jsx)(t.h3,{id:"create-an-rxcollection-with-an-encrypted-property",children:"Create an RxCollection with an encrypted property"}),(0,a.jsxs)(t.p,{children:["To define a field as being encrypted, you have to add it to the ",(0,a.jsx)(t.code,{children:"encrypted"})," fields list in the schema."]}),(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-ts",children:"const schema = {\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100\n },\n secret: {\n type: 'string'\n },\n },\n required: ['id']\n encrypted: ['secret']\n};\n\nawait db.addCollections({\n myDocuments: {\n schema\n }\n})\n"})})]}),"\n",(0,a.jsx)(t.h2,{id:"using-web-crypto-api",children:"Using Web-Crypto API"}),"\n",(0,a.jsxs)(t.p,{children:["For professionals, we have the ",(0,a.jsx)(t.code,{children:"web-crypto"})," ",(0,a.jsx)(t.a,{href:"/premium/",children:"\ud83d\udc51 premium"})," plugin which is faster and more secure:"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-ts",children:"import {\n wrappedKeyEncryptionWebCryptoStorage,\n createPassword\n} from 'rxdb-premium/plugins/encryption-web-crypto';\nimport { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';\n\n// wrap the normal storage with the encryption plugin\nconst encryptedIndexedDbStorage = wrappedKeyEncryptionWebCryptoStorage({\n storage: getRxStorageIndexedDB()\n});\n\nconst myPasswordObject = {\n // Algorithm can be oneOf: 'AES-CTR' | 'AES-CBC' | 'AES-GCM'\n algorithm: 'AES-CTR',\n password: 'myRandomPasswordWithMin8Length'\n};\n\n// create an encrypted database\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: encryptedIndexedDbStorage,\n password: myPasswordObject\n});\n\n/* ... */\n"})}),"\n",(0,a.jsx)(t.h2,{id:"changing-the-password",children:"Changing the password"}),"\n",(0,a.jsx)(t.p,{children:"The password is set database specific and it is not possible to change the password of a database. Opening an existing database with a different password will throw an error. To change the password you can either:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Use the ",(0,a.jsx)(t.a,{href:"/migration-storage.html",children:"storage migration plugin"})," to migrate the database state into a new database."]}),"\n",(0,a.jsxs)(t.li,{children:["Store a randomly created meta-password in a different RxDatabase as a value of a ",(0,a.jsx)(t.a,{href:"/rx-local-document.html",children:"local document"}),". Encrypt the meta password with the actual user password and read it out before creating the actual database."]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"encrypted-attachments",children:"Encrypted attachments"}),"\n",(0,a.jsxs)(t.p,{children:["To store the ",(0,a.jsx)(t.a,{href:"/rx-attachment.html",children:"attachments"})," data encrypted, you have to set ",(0,a.jsx)(t.code,{children:"encrypted: true"})," in the ",(0,a.jsx)(t.code,{children:"attachments"})," property of the schema."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-ts",children:"const mySchema = {\n version: 0,\n type: 'object',\n properties: {\n /* ... */\n },\n attachments: {\n encrypted: true // if true, the attachment-data will be encrypted with the db-password\n }\n};\n"})}),"\n",(0,a.jsx)(t.h2,{id:"encryption-and-workers",children:"Encryption and workers"}),"\n",(0,a.jsxs)(t.p,{children:["If you are using ",(0,a.jsx)(t.a,{href:"/rx-storage-worker.html",children:"Worker RxStorage"})," or ",(0,a.jsx)(t.a,{href:"/rx-storage-shared-worker.html",children:"SharedWorker RxStorage"})," with encryption, it's recommended to run encryption inside of the worker. Encryption can be very cpu intensive and would take away CPU-power from the main thread which is the main reason to use workers."]}),"\n",(0,a.jsx)(t.p,{children:"You do not need to worry about setting the password inside of the worker. The password will be set when calling createRxDatabase from the main thread, and will be passed internally to the storage in the worker automatically."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},7580:(e,t,n)=>{n.d(t,{g:()=>a});var r=n(4848);function a(e){const t=[];let n=null;return e.children.forEach((e=>{e.props.id?(n&&t.push(n),n={headline:e,paragraphs:[]}):n&&n.paragraphs.push(e)})),n&&t.push(n),(0,r.jsx)("div",{style:s.stepsContainer,children:t.map(((e,t)=>(0,r.jsxs)("div",{style:s.stepWrapper,children:[(0,r.jsxs)("div",{style:s.stepIndicator,children:[(0,r.jsxs)("div",{style:s.stepNumber,children:[t+1,"."]}),(0,r.jsx)("div",{style:s.verticalLine})]}),(0,r.jsxs)("div",{style:s.stepContent,children:[(0,r.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,t)=>(0,r.jsx)("div",{style:s.item,children:e},t)))]})]},t)))})}const s={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var r=n(6540);const a={},s=r.createContext(a);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/0e268d20.a2b11001.js b/docs/assets/js/0e268d20.e3a952e1.js similarity index 99% rename from docs/assets/js/0e268d20.a2b11001.js rename to docs/assets/js/0e268d20.e3a952e1.js index 43786e18dfd..760d4266ac1 100644 --- a/docs/assets/js/0e268d20.a2b11001.js +++ b/docs/assets/js/0e268d20.e3a952e1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2584],{135:(e,r,a)=>{a.d(r,{Pu:()=>t});const s={browser:.3,native:.4,performance:.35,server:.2,sourcecode:0},i=.05;function t(e){const r=e.getLatest()._data.data;return function(e){console.log("-------------------- calculatePrice:"),console.dir(e);let r=0;e.packages.forEach((e=>{const a=s[e];r+=a})),console.log("aimInPercent: "+r);let a=150+r/100*6e4;2===e.packages.length?a*=.95:e.packages.length>2&&(a*=.9);const t=Math.pow(e.teamSize,-.4);if(console.log("input.teamSize ("+a+") "+e.teamSize+" - pricePerDeveloper: "+t),a*=t*e.teamSize,e.packages.includes("sourcecode")){a*=1.75;const e=1520;a1200?100*Math.floor(a/100):50*Math.floor(a/50),{totalPrice:a}}({teamSize:r.developers,packages:r.packages})}},956:(e,r,a)=>{a.r(r),a.d(r,{FORM_VALUE_DOCUMENT_ID:()=>g,TEAM_SIZES:()=>j,default:()=>v});var s=a(797),i=a(6442),t=a(7143),n=a(6540),l=a(7593),o=a(4978),c=a(792),d=a(135),h=a(9136),m=a(7708),p=a(5520),x=a(106),u=a(4848);const g="premium-price-form",j=[1,3,6,12,24,30];let f;function b(){return f||(f=(async()=>{console.log("### FIND formValueDocPromise :;!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");const e=await Promise.all([a.e(1448),a.e(3304)]).then(a.bind(a,3304));console.log("aaaaaa dbmodule:"),console.dir(e);const r=await e.getDatabase();let s=await r.getLocal(g);return s||(s=await r.upsertLocal(g,{formSubmitted:!1,developers:j[1],packages:["browser"]})),console.log("form value doc:"),console.dir(s),s})()),f}function k(e){return(0,u.jsx)("input",{name:"package-"+e.packageName,type:"checkbox",className:"package-checkbox",checked:!!e.formValue?.packages.includes(e.packageName),readOnly:!0,onClick:()=>{(0,x.c)("calculate_premium_price",3,!0),e.onToggle()}})}function v(){const{siteConfig:e}=(0,s.A)(),r=(0,h.A)(),[a,c]=n.useState(!1),[g,j]=n.useState(null);(0,n.useEffect)((()=>{r&&(a||(c(!0),r&&(0,x.c)("open_pricing_page",1,!1),(async()=>{(await b()).$.pipe((0,m.T)((e=>e._data.data)),(0,p.F)(l.b)).subscribe((e=>{console.log("XXX new data:"),console.dir(e),j(e),async function(){const e=await b(),r=(0,d.Pu)(e);console.log("priceResult:"),console.log(JSON.stringify(r,null,4));const a=(0,o.ZN)(document.getElementById("price-calculator-result")),s=(0,o.ZN)(document.getElementById("total-per-project-per-month")),i=(0,o.ZN)(document.getElementById("total-per-project-per-year"));t=r.totalPrice,console.log("setPrice:"),console.dir(t),s.innerHTML=Math.ceil(t/12).toString(),i.innerHTML=Math.ceil(t).toString(),a.style.display="block";var t}()}))})()))}));const[f,v]=n.useState(!1);function w(e){return b().then((r=>r.incrementalModify((r=>(r.packages.includes(e)?r.packages=r.packages.filter((r=>r!==e)):r.packages.push(e),r)))))}return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(t.A,{children:[(0,u.jsx)("body",{className:"homepage"}),(0,u.jsx)("link",{rel:"canonical",href:"/premium/"})]}),(0,u.jsx)(i.A,{title:`Premium Plugins - ${e.title}`,description:"RxDB plugins for professionals. FAQ, pricing and license",children:(0,u.jsxs)("main",{children:[(0,u.jsx)("div",{className:"block first",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB ",(0,u.jsx)("b",{className:"underline",children:"Premium"})]}),(0,u.jsxs)("p",{style:{width:"80%"},children:["RxDB's Premium plugins offer advanced features and performance improvements designed for businesses and professionals. They are ideal for commercial or critical projects, providing ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"better performance"}),", a smaller build size, flexible storage engines, secure encryption and other features."]})]})}),(0,u.jsx)("div",{className:"block dark",id:"price-calculator-block",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsx)("h2",{children:"Price Calculator"}),(0,u.jsx)("div",{className:"price-calculator",children:(0,u.jsx)("div",{className:"price-calculator-inner",children:(0,u.jsx)("form",{id:"price-calculator-form",children:(0,u.jsxs)("div",{className:"packages",children:[(0,u.jsx)("h3",{children:"Packages:"}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"browser",onToggle:()=>w("browser"),formValue:g}),(0,u.jsx)("h4",{children:"Browser Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:"RxStorage OPFS"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:"RxStorage IndexedDB"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:"RxStorage Worker"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:"WebCrypto Encryption"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"native",onToggle:()=>w("native"),formValue:g}),(0,u.jsx)("h4",{children:"Native Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:"RxStorage SQLite"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:"RxStorage Filesystem Node"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"performance",onToggle:()=>w("performance"),formValue:g}),(0,u.jsx)("h4",{children:"Performance Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"RxStorage Sharding"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:"RxStorage Memory Mapped"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:"RxStorage Localstorage Meta Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:"RxStorage Shared Worker"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"server",onToggle:()=>w("server"),formValue:g}),(0,u.jsx)("h4",{children:"Server Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Fastify"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Koa"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)("input",{name:"package-utilities",type:"checkbox",className:"package-checkbox",defaultChecked:!0,disabled:!0}),(0,u.jsxs)("h4",{children:["Utilities Package ",(0,u.jsx)("b",{children:"(always included)"})]}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:"Logger"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:"Fulltext Search"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Vue"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Preact Signals"})})]})]})}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"clear"})]})})})}),(0,u.jsx)("div",{className:"price-calculator",id:"price-calculator-result",style:{marginBottom:90,display:"none"},children:(0,u.jsxs)("div",{className:"price-calculator-inner",children:[(0,u.jsx)("h4",{children:"Calculated Price:"}),(0,u.jsx)("br",{}),(0,u.jsxs)("div",{className:"inner",children:[(0,u.jsx)("span",{className:"price-label",children:"\u20ac"}),(0,u.jsx)("span",{id:"total-per-project-per-month",children:"XX"}),(0,u.jsx)("span",{className:"per-month",children:"/month"}),(0,u.jsx)("span",{className:"clear"})]}),(0,u.jsxs)("div",{className:"inner",children:["(billed yearly: ",(0,u.jsx)("span",{id:"total-per-project-per-year"})," \u20ac)"]}),(0,u.jsx)("br",{}),(0,u.jsx)("br",{}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"button",onClick:()=>{(0,x.c)("open_premium_submit_popup",20,!0),v(!0)},children:"Buy Now \xbb"}),(0,u.jsx)("div",{style:{fontSize:"70%",textAlign:"center"},children:"If you have any questions, see the FAQ below or fill out the Buy-Now Form to get in contact"}),(0,u.jsx)("div",{className:"clear"})]})})]})}),(0,u.jsx)("div",{className:"block",id:"faq",children:(0,u.jsxs)("div",{className:"content centered premium-faq",children:[(0,u.jsxs)("h2",{children:["F.A.Q. ",(0,u.jsx)("b",{children:"(click to toggle)"})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"What is the process for making a purchase?"}),(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:["Fill out the ",(0,u.jsx)("b",{children:"Buy now"})," form below."]}),(0,u.jsx)("li",{children:"You will get a license agreement that you can sign online."}),(0,u.jsx)("li",{children:"You will get an invoice via stripe.com."}),(0,u.jsxs)("li",{children:["After payment you get the access token that you can use to add the Premium plugins to your project with ",(0,u.jsx)("a",{href:"https://www.npmjs.com/package/rxdb-premium",target:"_blank",children:"these instructions"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a discount?"}),"There are multiple ways to get a discount:",(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Contritube to the RxDB github repository"}),(0,u.jsx)("p",{children:"If you have made significant contributions to the RxDB github repository, you can apply for a discount depending on your contribution."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Get 25% off by writing about how you use RxDB"}),(0,u.jsx)("p",{children:"On your company/project website, publish an article/blogpost about how you use RxDB in your project. Include how your setup looks like, how you use RxDB in that setup and what problems you had and how did you overcome them. You also need to link to the RxDB website or documentation pages."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Be active in the RxDB community"}),(0,u.jsx)("p",{children:"If you are active in the RxDB community and discord channel by helping others out or creating educational content like videos and tutorials, feel free to apply for a discount."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Solve one of the free-premium-tasks"}),(0,u.jsxs)("p",{children:["For private personal projects there is the option to solve one of the"," ",(0,u.jsx)("a",{href:"https://github.com/pubkey/rxdb/blob/master/orga/premium-tasks.md",target:"_blank",children:"Premium Tasks"})," ","to get a free 2 years access to the Premium Plugins."]})]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Do I need the Premium Plugins?"}),"RxDB Core is open source and many use cases can be implemented with the Open Core part of RxDB. There are many"," ",(0,u.jsx)("a",{href:"/rx-storage.html",target:"_blank",children:"RxStorage"})," ","options and all core plugins that are required for replication, schema validation, encryption and so on, are totally free. As soon as your application is more than a side project you can consider using the premium plugins as an easy way to improve your applications performance and reduce the build size.",(0,u.jsx)("br",{}),"The main benefit of the Premium Plugins is ",(0,u.jsx)("b",{children:"performance"}),". The Premium RxStorage implementations have a better performance so reading and writing data is much faster especially on low-end devices. You can find a performance comparison"," ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"here"}),". Also there are additional Premium Plugins that can be used to further optimize the performance of your application like the"," ",(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})," ","or the"," ",(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"Sharding"})," ","plugin."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a free trial period?"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:"We do not currently offer a free trial. Instead, we encourage you to explore RxDB's open-source core to evaluate the technology before purchasing the Premium Plugins."}),(0,u.jsxs)("li",{children:["Access to the Premium Plugins requires a signed licensing agreement, which safeguards both parties but also adds administrative overhead. For this reason, we cannot offer free trials or monthly subscriptions; Premium licenses are provided on an ",(0,u.jsx)("b",{children:"annual basis"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I install/build the premium plugins in my CI?"}),"Yes, you can safely install and use the Premium Plugins in your CI without additional payment."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Which payment methods are accepted?"}),(0,u.jsx)("b",{children:"Stripe.com"})," is used as payment processor so most known payment options like credit card, PayPal, SEPA transfer and others are available. A list of all options can be found"," ",(0,u.jsx)("a",{href:"https://stripe.com/docs/payments/payment-methods/overview",title:"stripe payment options",target:"_blank",children:"here"}),"."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Is there any tracking code inside of the premium plugins?"}),"No, the premium plugins themself do not contain any tracking code. When you build your application with RxDB and deploy it to production, it will not make requests from your users to any RxDB server."]})]})}),(0,u.jsx)("div",{className:"block dark",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB Premium Plugins ",(0,u.jsx)("b",{className:"underline",children:"Overview"})]}),(0,u.jsxs)("div",{className:"premium-blocks",children:[(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage IndexedDB"}),(0,u.jsxs)("p",{children:["A storage for browsers based on ",(0,u.jsx)("b",{children:"IndexedDB"}),". Has the best latency on writes and smallest build size."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage OPFS"}),(0,u.jsxs)("p",{children:["Currently the RxStorage with best data throughput that can be used in the browser. Based on the ",(0,u.jsx)("b",{children:"OPFS File System Access API"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SQLite"}),(0,u.jsxs)("p",{children:["A fast storage based on ",(0,u.jsx)("b",{children:"SQLite"})," for Servers and Hybrid Apps. Can be used with"," ",(0,u.jsx)("b",{children:"Node.js"}),", ",(0,u.jsx)("b",{children:"Electron"}),", ",(0,u.jsx)("b",{children:"React Native"}),", ",(0,u.jsx)("b",{children:"Capacitor"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SharedWorker"}),(0,u.jsxs)("p",{children:["A RxStorage wrapper to run the storage inside of a SharedWorker which improves the performance by taking CPU load away from the main process. Used in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Worker"}),(0,u.jsx)("p",{children:"A RxStorage wrapper to run the storage inside of a Worker which improves the performance by taking CPU load away from the main process."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Sharding"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that improves performance by applying the sharding technique."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Memory Mapped"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that creates a mapped in-memory copy which improves performance for the initial page load time and write & read operations."})]})})}),(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Query Optimizer"}),(0,u.jsx)("p",{children:"A tool to find the best index for a given query. You can use this during build time to find the best index and then use that index during runtime."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Localstorage Meta Optimizer"}),(0,u.jsxs)("p",{children:["A wrapper around any other storage which optimizes the initial page load one by using localstorage for meta key-value document. Only works in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"WebCrypto Encryption"}),(0,u.jsx)("p",{children:"A faster and more secure encryption plugin based on the Web Crypto API."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Filesystem Node"}),(0,u.jsxs)("p",{children:["A fast RxStorage based on the ",(0,u.jsx)("b",{children:"Node.js"})," Filesystem."]})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Logger"}),(0,u.jsx)("p",{children:"A logging plugin useful to debug performance problems and for monitoring with Application Performance Monitoring (APM) tools like Bugsnag, Datadog, Elastic, Sentry and others"})]})})}),(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Fastify Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with fastify instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Koa Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with Koa instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"FlexSearch"}),(0,u.jsx)("p",{children:"A plugin to efficiently run local fulltext search indexing and queries."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Vue"}),(0,u.jsx)("p",{children:"An extension for Vue.js to get vue shallow-ref objects to observe RxDB state instead of rxjs observables."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Preact Signals"}),(0,u.jsx)("p",{children:"An extension for react/preact to get preact signals to observe RxDB state instead of rxjs observables."})]})})})]})]})}),(0,u.jsx)(y,{open:f,onClose:()=>{v(!1)}})]})})]})}function y(e){let{onClose:r,open:a}=e;return(0,u.jsx)(c.A,{className:"modal-consulting-page",open:a,width:"auto",onCancel:()=>{r()},closeIcon:null,footer:null,children:(0,u.jsxs)("iframe",{style:{width:"100%",height:"70vh",borderRadius:"32px"},id:"request-project-form",src:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",children:["Your browser doesn't support iframes,"," ",(0,u.jsx)("a",{href:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",target:"_blank",rel:"nofollow",children:"Click here"})]})})}},4978:(e,r,a)=>{function s(e,r){if(!e)throw r||(r=""),new Error("ensureNotFalsy() is falsy: "+r);return e}a.d(r,{ZN:()=>s,bz:()=>i});var i={bufferSize:1,refCount:!0}},7593:(e,r,a)=>{function s(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var a,i;if(Array.isArray(e)){if((a=e.length)!==r.length)return!1;for(i=a;0!=i--;)if(!s(e[i],r[i]))return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===r.toString();var t=Object.keys(e);if((a=t.length)!==Object.keys(r).length)return!1;for(i=a;0!=i--;)if(!Object.prototype.hasOwnProperty.call(r,t[i]))return!1;for(i=a;0!=i--;){var n=t[i];if(!s(e[n],r[n]))return!1}return!0}return e!=e&&r!=r}a.d(r,{b:()=>s})}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2584],{135:(e,r,a)=>{a.d(r,{Pu:()=>t});const s={browser:.3,native:.4,performance:.35,server:.2,sourcecode:0},i=.05;function t(e){const r=e.getLatest()._data.data;return function(e){console.log("-------------------- calculatePrice:"),console.dir(e);let r=0;e.packages.forEach((e=>{const a=s[e];r+=a})),console.log("aimInPercent: "+r);let a=150+r/100*6e4;2===e.packages.length?a*=.95:e.packages.length>2&&(a*=.9);const t=Math.pow(e.teamSize,-.4);if(console.log("input.teamSize ("+a+") "+e.teamSize+" - pricePerDeveloper: "+t),a*=t*e.teamSize,e.packages.includes("sourcecode")){a*=1.75;const e=1520;a1200?100*Math.floor(a/100):50*Math.floor(a/50),{totalPrice:a}}({teamSize:r.developers,packages:r.packages})}},956:(e,r,a)=>{a.r(r),a.d(r,{FORM_VALUE_DOCUMENT_ID:()=>g,TEAM_SIZES:()=>j,default:()=>v});var s=a(797),i=a(6442),t=a(7143),n=a(6540),l=a(7593),o=a(4978),c=a(792),d=a(135),h=a(9136),m=a(7708),p=a(5520),x=a(106),u=a(4848);const g="premium-price-form",j=[1,3,6,12,24,30];let f;function b(){return f||(f=(async()=>{console.log("### FIND formValueDocPromise :;!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");const e=await Promise.all([a.e(7175),a.e(8164)]).then(a.bind(a,8164));console.log("aaaaaa dbmodule:"),console.dir(e);const r=await e.getDatabase();let s=await r.getLocal(g);return s||(s=await r.upsertLocal(g,{formSubmitted:!1,developers:j[1],packages:["browser"]})),console.log("form value doc:"),console.dir(s),s})()),f}function k(e){return(0,u.jsx)("input",{name:"package-"+e.packageName,type:"checkbox",className:"package-checkbox",checked:!!e.formValue?.packages.includes(e.packageName),readOnly:!0,onClick:()=>{(0,x.c)("calculate_premium_price",3,!0),e.onToggle()}})}function v(){const{siteConfig:e}=(0,s.A)(),r=(0,h.A)(),[a,c]=n.useState(!1),[g,j]=n.useState(null);(0,n.useEffect)((()=>{r&&(a||(c(!0),r&&(0,x.c)("open_pricing_page",1,!1),(async()=>{(await b()).$.pipe((0,m.T)((e=>e._data.data)),(0,p.F)(l.b)).subscribe((e=>{console.log("XXX new data:"),console.dir(e),j(e),async function(){const e=await b(),r=(0,d.Pu)(e);console.log("priceResult:"),console.log(JSON.stringify(r,null,4));const a=(0,o.ZN)(document.getElementById("price-calculator-result")),s=(0,o.ZN)(document.getElementById("total-per-project-per-month")),i=(0,o.ZN)(document.getElementById("total-per-project-per-year"));t=r.totalPrice,console.log("setPrice:"),console.dir(t),s.innerHTML=Math.ceil(t/12).toString(),i.innerHTML=Math.ceil(t).toString(),a.style.display="block";var t}()}))})()))}));const[f,v]=n.useState(!1);function w(e){return b().then((r=>r.incrementalModify((r=>(r.packages.includes(e)?r.packages=r.packages.filter((r=>r!==e)):r.packages.push(e),r)))))}return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(t.A,{children:[(0,u.jsx)("body",{className:"homepage"}),(0,u.jsx)("link",{rel:"canonical",href:"/premium/"})]}),(0,u.jsx)(i.A,{title:`Premium Plugins - ${e.title}`,description:"RxDB plugins for professionals. FAQ, pricing and license",children:(0,u.jsxs)("main",{children:[(0,u.jsx)("div",{className:"block first",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB ",(0,u.jsx)("b",{className:"underline",children:"Premium"})]}),(0,u.jsxs)("p",{style:{width:"80%"},children:["RxDB's Premium plugins offer advanced features and performance improvements designed for businesses and professionals. They are ideal for commercial or critical projects, providing ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"better performance"}),", a smaller build size, flexible storage engines, secure encryption and other features."]})]})}),(0,u.jsx)("div",{className:"block dark",id:"price-calculator-block",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsx)("h2",{children:"Price Calculator"}),(0,u.jsx)("div",{className:"price-calculator",children:(0,u.jsx)("div",{className:"price-calculator-inner",children:(0,u.jsx)("form",{id:"price-calculator-form",children:(0,u.jsxs)("div",{className:"packages",children:[(0,u.jsx)("h3",{children:"Packages:"}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"browser",onToggle:()=>w("browser"),formValue:g}),(0,u.jsx)("h4",{children:"Browser Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:"RxStorage OPFS"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:"RxStorage IndexedDB"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:"RxStorage Worker"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:"WebCrypto Encryption"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"native",onToggle:()=>w("native"),formValue:g}),(0,u.jsx)("h4",{children:"Native Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:"RxStorage SQLite"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:"RxStorage Filesystem Node"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"performance",onToggle:()=>w("performance"),formValue:g}),(0,u.jsx)("h4",{children:"Performance Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"RxStorage Sharding"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:"RxStorage Memory Mapped"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:"RxStorage Localstorage Meta Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:"RxStorage Shared Worker"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(k,{packageName:"server",onToggle:()=>w("server"),formValue:g}),(0,u.jsx)("h4",{children:"Server Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Fastify"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Koa"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)("input",{name:"package-utilities",type:"checkbox",className:"package-checkbox",defaultChecked:!0,disabled:!0}),(0,u.jsxs)("h4",{children:["Utilities Package ",(0,u.jsx)("b",{children:"(always included)"})]}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:"Logger"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:"Fulltext Search"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Vue"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Preact Signals"})})]})]})}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"clear"})]})})})}),(0,u.jsx)("div",{className:"price-calculator",id:"price-calculator-result",style:{marginBottom:90,display:"none"},children:(0,u.jsxs)("div",{className:"price-calculator-inner",children:[(0,u.jsx)("h4",{children:"Calculated Price:"}),(0,u.jsx)("br",{}),(0,u.jsxs)("div",{className:"inner",children:[(0,u.jsx)("span",{className:"price-label",children:"\u20ac"}),(0,u.jsx)("span",{id:"total-per-project-per-month",children:"XX"}),(0,u.jsx)("span",{className:"per-month",children:"/month"}),(0,u.jsx)("span",{className:"clear"})]}),(0,u.jsxs)("div",{className:"inner",children:["(billed yearly: ",(0,u.jsx)("span",{id:"total-per-project-per-year"})," \u20ac)"]}),(0,u.jsx)("br",{}),(0,u.jsx)("br",{}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"button",onClick:()=>{(0,x.c)("open_premium_submit_popup",20,!0),v(!0)},children:"Buy Now \xbb"}),(0,u.jsx)("div",{style:{fontSize:"70%",textAlign:"center"},children:"If you have any questions, see the FAQ below or fill out the Buy-Now Form to get in contact"}),(0,u.jsx)("div",{className:"clear"})]})})]})}),(0,u.jsx)("div",{className:"block",id:"faq",children:(0,u.jsxs)("div",{className:"content centered premium-faq",children:[(0,u.jsxs)("h2",{children:["F.A.Q. ",(0,u.jsx)("b",{children:"(click to toggle)"})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"What is the process for making a purchase?"}),(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:["Fill out the ",(0,u.jsx)("b",{children:"Buy now"})," form below."]}),(0,u.jsx)("li",{children:"You will get a license agreement that you can sign online."}),(0,u.jsx)("li",{children:"You will get an invoice via stripe.com."}),(0,u.jsxs)("li",{children:["After payment you get the access token that you can use to add the Premium plugins to your project with ",(0,u.jsx)("a",{href:"https://www.npmjs.com/package/rxdb-premium",target:"_blank",children:"these instructions"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a discount?"}),"There are multiple ways to get a discount:",(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Contritube to the RxDB github repository"}),(0,u.jsx)("p",{children:"If you have made significant contributions to the RxDB github repository, you can apply for a discount depending on your contribution."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Get 25% off by writing about how you use RxDB"}),(0,u.jsx)("p",{children:"On your company/project website, publish an article/blogpost about how you use RxDB in your project. Include how your setup looks like, how you use RxDB in that setup and what problems you had and how did you overcome them. You also need to link to the RxDB website or documentation pages."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Be active in the RxDB community"}),(0,u.jsx)("p",{children:"If you are active in the RxDB community and discord channel by helping others out or creating educational content like videos and tutorials, feel free to apply for a discount."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Solve one of the free-premium-tasks"}),(0,u.jsxs)("p",{children:["For private personal projects there is the option to solve one of the"," ",(0,u.jsx)("a",{href:"https://github.com/pubkey/rxdb/blob/master/orga/premium-tasks.md",target:"_blank",children:"Premium Tasks"})," ","to get a free 2 years access to the Premium Plugins."]})]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Do I need the Premium Plugins?"}),"RxDB Core is open source and many use cases can be implemented with the Open Core part of RxDB. There are many"," ",(0,u.jsx)("a",{href:"/rx-storage.html",target:"_blank",children:"RxStorage"})," ","options and all core plugins that are required for replication, schema validation, encryption and so on, are totally free. As soon as your application is more than a side project you can consider using the premium plugins as an easy way to improve your applications performance and reduce the build size.",(0,u.jsx)("br",{}),"The main benefit of the Premium Plugins is ",(0,u.jsx)("b",{children:"performance"}),". The Premium RxStorage implementations have a better performance so reading and writing data is much faster especially on low-end devices. You can find a performance comparison"," ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"here"}),". Also there are additional Premium Plugins that can be used to further optimize the performance of your application like the"," ",(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})," ","or the"," ",(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"Sharding"})," ","plugin."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a free trial period?"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:"We do not currently offer a free trial. Instead, we encourage you to explore RxDB's open-source core to evaluate the technology before purchasing the Premium Plugins."}),(0,u.jsxs)("li",{children:["Access to the Premium Plugins requires a signed licensing agreement, which safeguards both parties but also adds administrative overhead. For this reason, we cannot offer free trials or monthly subscriptions; Premium licenses are provided on an ",(0,u.jsx)("b",{children:"annual basis"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I install/build the premium plugins in my CI?"}),"Yes, you can safely install and use the Premium Plugins in your CI without additional payment."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Which payment methods are accepted?"}),(0,u.jsx)("b",{children:"Stripe.com"})," is used as payment processor so most known payment options like credit card, PayPal, SEPA transfer and others are available. A list of all options can be found"," ",(0,u.jsx)("a",{href:"https://stripe.com/docs/payments/payment-methods/overview",title:"stripe payment options",target:"_blank",children:"here"}),"."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Is there any tracking code inside of the premium plugins?"}),"No, the premium plugins themself do not contain any tracking code. When you build your application with RxDB and deploy it to production, it will not make requests from your users to any RxDB server."]})]})}),(0,u.jsx)("div",{className:"block dark",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB Premium Plugins ",(0,u.jsx)("b",{className:"underline",children:"Overview"})]}),(0,u.jsxs)("div",{className:"premium-blocks",children:[(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage IndexedDB"}),(0,u.jsxs)("p",{children:["A storage for browsers based on ",(0,u.jsx)("b",{children:"IndexedDB"}),". Has the best latency on writes and smallest build size."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage OPFS"}),(0,u.jsxs)("p",{children:["Currently the RxStorage with best data throughput that can be used in the browser. Based on the ",(0,u.jsx)("b",{children:"OPFS File System Access API"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SQLite"}),(0,u.jsxs)("p",{children:["A fast storage based on ",(0,u.jsx)("b",{children:"SQLite"})," for Servers and Hybrid Apps. Can be used with"," ",(0,u.jsx)("b",{children:"Node.js"}),", ",(0,u.jsx)("b",{children:"Electron"}),", ",(0,u.jsx)("b",{children:"React Native"}),", ",(0,u.jsx)("b",{children:"Capacitor"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SharedWorker"}),(0,u.jsxs)("p",{children:["A RxStorage wrapper to run the storage inside of a SharedWorker which improves the performance by taking CPU load away from the main process. Used in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Worker"}),(0,u.jsx)("p",{children:"A RxStorage wrapper to run the storage inside of a Worker which improves the performance by taking CPU load away from the main process."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Sharding"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that improves performance by applying the sharding technique."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Memory Mapped"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that creates a mapped in-memory copy which improves performance for the initial page load time and write & read operations."})]})})}),(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Query Optimizer"}),(0,u.jsx)("p",{children:"A tool to find the best index for a given query. You can use this during build time to find the best index and then use that index during runtime."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Localstorage Meta Optimizer"}),(0,u.jsxs)("p",{children:["A wrapper around any other storage which optimizes the initial page load one by using localstorage for meta key-value document. Only works in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"WebCrypto Encryption"}),(0,u.jsx)("p",{children:"A faster and more secure encryption plugin based on the Web Crypto API."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Filesystem Node"}),(0,u.jsxs)("p",{children:["A fast RxStorage based on the ",(0,u.jsx)("b",{children:"Node.js"})," Filesystem."]})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Logger"}),(0,u.jsx)("p",{children:"A logging plugin useful to debug performance problems and for monitoring with Application Performance Monitoring (APM) tools like Bugsnag, Datadog, Elastic, Sentry and others"})]})})}),(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Fastify Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with fastify instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Koa Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with Koa instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"FlexSearch"}),(0,u.jsx)("p",{children:"A plugin to efficiently run local fulltext search indexing and queries."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Vue"}),(0,u.jsx)("p",{children:"An extension for Vue.js to get vue shallow-ref objects to observe RxDB state instead of rxjs observables."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Preact Signals"}),(0,u.jsx)("p",{children:"An extension for react/preact to get preact signals to observe RxDB state instead of rxjs observables."})]})})})]})]})}),(0,u.jsx)(y,{open:f,onClose:()=>{v(!1)}})]})})]})}function y(e){let{onClose:r,open:a}=e;return(0,u.jsx)(c.A,{className:"modal-consulting-page",open:a,width:"auto",onCancel:()=>{r()},closeIcon:null,footer:null,children:(0,u.jsxs)("iframe",{style:{width:"100%",height:"70vh",borderRadius:"32px"},id:"request-project-form",src:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",children:["Your browser doesn't support iframes,"," ",(0,u.jsx)("a",{href:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",target:"_blank",rel:"nofollow",children:"Click here"})]})})}},4978:(e,r,a)=>{function s(e,r){if(!e)throw r||(r=""),new Error("ensureNotFalsy() is falsy: "+r);return e}a.d(r,{ZN:()=>s,bz:()=>i});var i={bufferSize:1,refCount:!0}},7593:(e,r,a)=>{function s(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var a,i;if(Array.isArray(e)){if((a=e.length)!==r.length)return!1;for(i=a;0!=i--;)if(!s(e[i],r[i]))return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===r.toString();var t=Object.keys(e);if((a=t.length)!==Object.keys(r).length)return!1;for(i=a;0!=i--;)if(!Object.prototype.hasOwnProperty.call(r,t[i]))return!1;for(i=a;0!=i--;){var n=t[i];if(!s(e[n],r[n]))return!1}return!0}return e!=e&&r!=r}a.d(r,{b:()=>s})}}]); \ No newline at end of file diff --git a/docs/assets/js/1448.b56cd644.js b/docs/assets/js/1448.b56cd644.js deleted file mode 100644 index 95cc37880e0..00000000000 --- a/docs/assets/js/1448.b56cd644.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[1448],{235:(e,t,n)=>{"use strict";n.d(t,{R0:()=>u,lI:()=>i});var r=n(1693);function o(e){return e[e.length-1]}function i(e){return(t=o(e))&&(0,r.T)(t.schedule)?e.pop():void 0;var t}function u(e,t){return"number"==typeof o(e)?e.pop():t}},374:(e,t,n)=>{"use strict";n.d(t,{Zz:()=>i,dF:()=>o});var r=n(744);function o(e){return e instanceof s?e:new s(e)}function i(...e){let t=0;return o((()=>{for(;t{const e=n.next();if(e.done)throw a;return e.value}}else if(e instanceof Array){const n=e,r=n.length;let o=0;t=()=>{if(o0?this.push(2,e):this}drop(e){return e>0?this.push(3,e):this}transform(e){const t=this;let n;return o((()=>(n||(n=o(e(t.value()))),n.next())))}value(){return this.isDone||(this.isDone=this.getNext(!0).done),this.yieldedValues}each(e){for(;;){const t=this.next();if(t.done)break;if(!1===e(t.value))return!1}return!0}reduce(e,t){let n=this.next();for(void 0!==t||n.done||(t=n.value,n=this.next());!n.done;)t=e(t,n.value),n=this.next();return t}size(){return this.reduce(((e,t)=>++e),0)}[Symbol.iterator](){return this}}},703:(e,t,n)=>{"use strict";n.d(t,{X2:()=>I});Promise.resolve(!1),Promise.resolve(!0);var r=Promise.resolve();function o(e,t){return e||(e=0),new Promise((function(n){return setTimeout((function(){return n(t)}),e)}))}function i(){return Math.random().toString(36).substring(2)}var u=0;function a(){var e=1e3*Date.now();return e<=u&&(e=u+1),u=e,e}var s={create:function(e){var t={time:a(),messagesCallback:null,bc:new BroadcastChannel(e),subFns:[]};return t.bc.onmessage=function(e){t.messagesCallback&&t.messagesCallback(e.data)},t},close:function(e){e.bc.close(),e.subFns=[]},onMessage:function(e,t){e.messagesCallback=t},postMessage:function(e,t){try{return e.bc.postMessage(t,!1),r}catch(n){return Promise.reject(n)}},canBeUsed:function(){if("undefined"!=typeof globalThis&&globalThis.Deno&&globalThis.Deno.args)return!0;if("undefined"==typeof window&&"undefined"==typeof self||"function"!=typeof BroadcastChannel)return!1;if(BroadcastChannel._pubkey)throw new Error("BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill");return!0},type:"native",averageResponseTime:function(){return 150},microSeconds:a},c=n(5525);function l(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=JSON.parse(JSON.stringify(e));return void 0===t.webWorkerSupport&&(t.webWorkerSupport=!0),t.idb||(t.idb={}),t.idb.ttl||(t.idb.ttl=45e3),t.idb.fallbackInterval||(t.idb.fallbackInterval=150),e.idb&&"function"==typeof e.idb.onclose&&(t.idb.onclose=e.idb.onclose),t.localstorage||(t.localstorage={}),t.localstorage.removeTimeout||(t.localstorage.removeTimeout=6e4),e.methods&&(t.methods=e.methods),t.node||(t.node={}),t.node.ttl||(t.node.ttl=12e4),t.node.maxParallelWrites||(t.node.maxParallelWrites=2048),void 0===t.node.useFastPath&&(t.node.useFastPath=!0),t}var f="messages",h={durability:"relaxed"};function d(){if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof window){if(void 0!==window.mozIndexedDB)return window.mozIndexedDB;if(void 0!==window.webkitIndexedDB)return window.webkitIndexedDB;if(void 0!==window.msIndexedDB)return window.msIndexedDB}return!1}function p(e){e.commit&&e.commit()}function y(e,t){var n=e.transaction(f,"readonly",h),r=n.objectStore(f),o=[],i=IDBKeyRange.bound(t+1,1/0);if(r.getAll){var u=r.getAll(i);return new Promise((function(e,t){u.onerror=function(e){return t(e)},u.onsuccess=function(t){e(t.target.result)}}))}return new Promise((function(e,u){var a=function(){try{return i=IDBKeyRange.bound(t+1,1/0),r.openCursor(i)}catch(e){return r.openCursor()}}();a.onerror=function(e){return u(e)},a.onsuccess=function(r){var i=r.target.result;i?i.value.ide.lastCursorId&&(e.lastCursorId=t.id),t})).filter((function(t){return function(e,t){return!(e.uuid===t.uuid||t.eMIs.has(e.id)||e.data.time0||e._addEL.internal.length>0}function M(e,t,n){e._addEL[t].push(n),function(e){if(!e._iL&&T(e)){var t=function(t){e._addEL[t.type].forEach((function(e){t.time>=e.time&&e.fn(t.data)}))},n=e.method.microSeconds();e._prepP?e._prepP.then((function(){e._iL=!0,e.method.onMessage(e._state,t,n)})):(e._iL=!0,e.method.onMessage(e._state,t,n))}}(e)}function D(e,t,n){e._addEL[t]=e._addEL[t].filter((function(e){return e!==n})),function(e){if(e._iL&&!T(e)){e._iL=!1;var t=e.method.microSeconds();e.method.onMessage(e._state,null,t)}}(e)}I._pubkey=!0,I.prototype={postMessage:function(e){if(this.closed)throw new Error("BroadcastChannel.postMessage(): Cannot post message after channel has closed "+JSON.stringify(e));return K(this,"message",e)},postInternal:function(e){return K(this,"internal",e)},set onmessage(e){var t={time:this.method.microSeconds(),fn:e};D(this,"message",this._onML),e&&"function"==typeof e?(this._onML=t,M(this,"message",t)):this._onML=null},addEventListener:function(e,t){M(this,e,{time:this.method.microSeconds(),fn:t})},removeEventListener:function(e,t){D(this,e,this._addEL[e].find((function(e){return e.fn===t})))},close:function(){var e=this;if(!this.closed){A.delete(this),this.closed=!0;var t=this._prepP?this._prepP:r;return this._onML=null,this._addEL.message=[],t.then((function(){return Promise.all(Array.from(e._uMP))})).then((function(){return Promise.all(e._befC.map((function(e){return e()})))})).then((function(){return e.method.close(e._state)}))}},get type(){return this.method.type},get isClosed(){return this.closed}}},744:(e,t,n)=>{"use strict";n.d(t,{$P:()=>k,$z:()=>G,B2:()=>J,Bq:()=>$,E$:()=>L,Et:()=>g,Gv:()=>_,Hq:()=>o,Im:()=>C,KL:()=>j,KY:()=>ne,Kg:()=>b,Lm:()=>m,Pw:()=>v,R:()=>i,RV:()=>S,Rm:()=>Z,S8:()=>ue,Tn:()=>E,UD:()=>p,W_:()=>u,Z4:()=>x,Zo:()=>ie,cy:()=>w,d8:()=>r,dj:()=>X,eC:()=>K,gD:()=>P,gd:()=>O,h1:()=>B,hd:()=>Q,mg:()=>N,n4:()=>U,oU:()=>a,vA:()=>y,vN:()=>A,yT:()=>re,zy:()=>T});class r extends Error{}const o=2147483647,i=-2147483648,u=Number.MAX_SAFE_INTEGER,a=Number.MIN_SAFE_INTEGER,s=Symbol("missing"),c=Object.freeze(new Error("mingo: cycle detected while processing object/array")),l=/^\[object ([a-zA-Z0-9]+)\]$/,f=e=>{const t=V(e);let n=0,r=t.length;for(;r;)n=(n<<5)-n^t.charCodeAt(--r);return n>>>0},h=new Set(["null","undefined","boolean","number","string","date","regexp"]),d={null:0,undefined:0,number:1,string:2,object:3,array:4,boolean:5,date:6,regexp:7,function:8},p=(e,t)=>{e===s&&(e=void 0),t===s&&(t=void 0);const[n,r]=[e,t].map((e=>d[v(e).toLowerCase()]));return n!==r?n-r:1===n||2===n||6===n?et?1:0:U(e,t)?0:et?1:0};function y(e,t){if(!e)throw new r(t)}const v=e=>l.exec(Object.prototype.toString.call(e))[1],m=e=>"boolean"==typeof e,b=e=>"string"==typeof e,g=e=>!isNaN(e)&&"number"==typeof e,w=Array.isArray,_=e=>{if(!e)return!1;const t=Object.getPrototypeOf(e);return(t===Object.prototype||null===t)&&"[object Object]"===Object.prototype.toString.call(e)},x=e=>e===Object(e),k=e=>e instanceof Date,O=e=>e instanceof RegExp,E=e=>"function"==typeof e,P=e=>null==e,S=(e,t)=>e.includes(t),j=(e,t)=>!S(e,t),A=(e,t=!0)=>!!e||t&&""===e,C=e=>P(e)||b(e)&&!e||e instanceof Array&&0===e.length||_(e)&&0===Object.keys(e).length,I=e=>e===s,K=e=>e instanceof Array?e:[e],T=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),M=e=>"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView(e),D=[k,O,M],R=(e,t)=>{if(P(e))return e;if(t.has(e))throw c;const n=e.constructor;if(D.some((t=>t(e))))return new n(e);try{if(t.add(e),w(e))return e.map((e=>R(e,t)));if(_(e)){const n={};for(const r in e)n[r]=R(e[r],t);return n}}finally{t.delete(e)}return e},N=e=>R(e,new Set),q=(e,t)=>_(e)&&_(t)||w(e)&&w(t);function B(e,t,n){if(n=n||{flatten:!1},I(e)||P(e))return t;if(I(t)||P(t))return e;if(!q(e,t)){if(n.skipValidation)return t||e;throw Error("mismatched types. must both be array or object")}if(n.skipValidation=!0,w(e)){const r=e,o=t;if(n.flatten){let e=0,i=0;for(;e{const i=W(r,t);n.has(i)?n.get(i).some((t=>U(e[t],r)))||n.get(i).push(o):n.set(i,[o])})),n}function L(e,t=f){if(e.some((e=>0==e.length)))return[];if(1===e.length)return Array.from(e);const n=function(e,t,n=p){if(C(e))return e;const r=new Array,o=new Array;for(let i=0;in(e[0],t[0]))),X(o,r.map((e=>e[1])))}(e.map(((e,t)=>[t,e.length])),(e=>e[1])),r=e[n[0][0]],o=F(r,t),i=new Map,u=new Array;return o.forEach(((t,o)=>{const a=t.map((e=>r[e])),c=a.map((e=>0)),l=a.map((e=>[n[0][0],0]));let f=!1;for(let r=1;rs[e]));f=a.map(((n,u)=>e.some(((e,a)=>{const s=c[u];return U(n,e)&&(c[u]++,tt===e.length-1?[a[n],l[n]]:s)).filter((e=>e!==s)))})),u.sort(((e,t)=>{const[n,[r,o]]=e,[i,[u,a]]=t,s=p(r,u);return 0!==s?s:p(o,a)})).map((e=>e[0]))}function $(e,t=0){const n=new Array;return function e(t,r){for(let o=0,i=t.length;o0||r<0)?e(t[o],Math.max(-1,r-1)):n.push(t[o])}(e,t),n}function U(e,t){if(e===t||Object.is(e,t))return!0;const n=!!e&&e.constructor||e;if(null===e||null===t||void 0===e||void 0===t||n!==t.constructor||n===Function)return!1;if(n===Array||n===Object){const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;if(new Set([...n,...r]).size!=n.length)return!1;for(const o of n)if(!U(e[o],t[o]))return!1;return!0}const r=Object.getPrototypeOf(e);return(M(e)||r!==Object.prototype&&r!==Array.prototype&&Object.prototype.hasOwnProperty.call(r,"toString"))&&e.toString()===t.toString()}const z=(e,t)=>{if(null===e)return"null";if(void 0===e)return"undefined";const n=e.constructor;switch(n){case RegExp:case Number:case Boolean:case Function:case Symbol:return e.toString();case String:return JSON.stringify(e);case Date:return e.toISOString()}if(M(e))return n.name+"["+e.toString()+"]";if(t.has(e))throw c;try{if(t.add(e),w(e))return"["+e.map((e=>z(e,t))).join(",")+"]";if(n===Object)return"{"+Object.keys(e).sort().map((n=>n+":"+z(e[n],t))).join(",")+"}";const r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==Array.prototype&&Object.prototype.hasOwnProperty.call(r,"toString"))return n.name+"("+JSON.stringify(e.toString())+")";const[o,i]=(e=>{let[t,n]=[Object.getPrototypeOf(e),Object.getOwnPropertyNames(e)],r=t;for(;!n.length&&t!==Object.prototype&&t!==Array.prototype;)r=t,n=Object.getOwnPropertyNames(t),t=Object.getPrototypeOf(t);const o={};return n.forEach((t=>o[t]=e[t])),[o,r]})(e);return n.name+z(o,t)}finally{t.delete(e)}},V=e=>z(e,new Set);function W(e,t){return t=t||f,P(e)?null:t(e).toString()}function G(e,t,n=f){if(e.length<1)return new Map;const r=new Map,o=new Map;for(let i=0;iU(e,a))):null;P(e)?(o.set(a,[u]),r.has(s)?r.get(s).push(a):r.set(s,[a])):o.get(e).push(u)}}return o}const Y=5e4;function X(e,...t){return e instanceof Array?t.reduce(((e,t)=>{let n=Math.ceil(t.length/Y),r=0;for(;n-- >0;)Array.prototype.push.apply(e,t.slice(r,r+Y)),r+=Y;return e}),e):t.filter(x).reduce(((e,t)=>(Object.assign(e,t),e)),e)}function H(e,t){return x(e)?e[t]:void 0}function Q(e,t,n){let r=0;const o=h.has(v(e).toLowerCase())?e:function e(t,n){let o=t;for(let i=0;i0)break;r+=1;const t=n.slice(i);o=o.reduce(((n,r)=>{const o=e(r,t);return void 0!==o&&n.push(o),n}),[]);break}if(o=H(o,t),void 0===o)break}return o}(e,t.split("."));return o instanceof Array&&n?.unwrapArray?function(e,t){if(t<1)return e;for(;t--&&1===e.length;)e=e[0];return e}(o,r):o}function Z(e,t,n){const r=t.split("."),o=r[0],i=r.slice(1).join("."),u=null!==/^\d+$/.exec(o),a=r.length>1;let c,l;if(e instanceof Array)if(u)c=H(e,Number(o)),a&&(c=Z(c,i,n)),c=[c];else{c=[];for(const r of e)l=Z(r,t,n),n?.preserveMissing?(void 0===l&&(l=s),c.push(l)):void 0!==l&&c.push(l)}else{if(l=H(e,o),a&&(l=Z(l,i,n)),void 0===l)return;c=n?.preserveKeys?{...e}:{},c[o]=l}return c}function J(e){if(e instanceof Array)for(let t=e.length-1;t>=0;t--)e[t]===s?e.splice(t,1):J(e[t]);else if(_(e))for(const t in e)T(e,t)&&J(e[t])}const ee=/^\d+$/;function te(e,t,n,r){const o=t.split("."),i=o[0],u=o.slice(1).join(".");if(1===o.length)(_(e)||w(e)&&ee.test(i))&&n(e,i);else{r?.buildGraph&&P(e[i])&&(e[i]={});const t=e[i];if(!t)return;const a=!!(o.length>1&&ee.test(o[1]));t instanceof Array&&r?.descendArray&&!a?t.forEach((e=>te(e,u,n,r))):te(t,u,n,r)}}function ne(e,t,n){te(e,t,((e,t)=>{e[t]=E(n)?n(e[t]):n}),{buildGraph:!0})}function re(e,t,n){te(e,t,((e,t)=>{if(e instanceof Array){if(/^\d+$/.test(t))e.splice(parseInt(t),1);else if(n&&n.descendArray)for(const n of e)_(n)&&delete n[t]}else _(e)&&delete e[t]}),n)}const oe=/^\$[a-zA-Z0-9_]+$/;function ie(e){return oe.test(e)}function ue(e){if(h.has(v(e).toLowerCase()))return O(e)?{$regex:e}:{$eq:e};if(x(e)){const t=e;if(!Object.keys(t).some(ie))return{$eq:e};if(T(e,"$regex")){const t={...e};return t.$regex=new RegExp(e.$regex,e.$options),delete t.$options,t}}return e}},1073:(e,t,n)=>{"use strict";n.d(t,{Pp:()=>o,WP:()=>i});n(2779);n(744);var r=n(6827);const o=(0,r.jm)(r.Pp),i=(0,r.jm)(r.WP)},1446:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(8896),o=n(1693);function i(e){return(0,o.T)(e[r.s])}},1449:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(1576);function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,(0,r.A)(e,t)}},1576:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}n.d(t,{A:()=>r})},1692:(e,t,n)=>{"use strict";n.d(t,{X:()=>s});var r=n(2779),o=n(7681),i=n(374),u=n(744);class a{constructor(e,t,n,r){this.source=e,this.predicate=t,this.projection=n,this.options=r,this.operators=[],this.result=null,this.buffer=[]}fetch(){return this.result||((0,u.Gv)(this.projection)&&this.operators.push({$project:this.projection}),this.result=(0,i.dF)(this.source).filter(this.predicate),this.operators.length>0&&(this.result=new o.u(this.operators,this.options).stream(this.result))),this.result}fetchAll(){const e=(0,i.dF)([...this.buffer]);return this.buffer=[],(0,i.Zz)(e,this.fetch())}all(){return this.fetchAll().value()}count(){return this.all().length}skip(e){return this.operators.push({$skip:e}),this}limit(e){return this.operators.push({$limit:e}),this}sort(e){return this.operators.push({$sort:e}),this}collation(e){return this.options={...this.options,collation:e},this}next(){if(this.buffer.length>0)return this.buffer.pop();const e=this.fetch().next();return e.done?void 0:e.value}hasNext(){if(this.buffer.length>0)return!0;const e=this.fetch().next();return!e.done&&(this.buffer.push(e.value),!0)}map(e){return this.all().map(e)}forEach(e){this.all().forEach(e)}[Symbol.iterator](){return this.fetchAll()}}class s{constructor(e,t){this.condition=e,this.options=(0,r.B3)(t),this.compiled=[],this.compile()}compile(){(0,u.vA)((0,u.Gv)(this.condition),`query criteria must be an object: ${JSON.stringify(this.condition)}`);const e={};for(const[t,n]of Object.entries(this.condition)){if("$where"===t)Object.assign(e,{field:t,expr:n});else if((0,u.RV)(["$and","$or","$nor","$expr","$jsonSchema"],t))this.processOperator(t,t,n);else{(0,u.vA)(!(0,u.Zo)(t),`unknown top level operator: ${t}`);for(const[e,r]of Object.entries((0,u.S8)(n)))this.processOperator(t,e,r)}e.field&&this.processOperator(e.field,e.field,e.expr)}}processOperator(e,t,n){const o=(0,r.F5)(r.hu.QUERY,t,this.options);if(!o)throw new u.d8(`unknown query operator ${t}`);const i=o(e,n,this.options);this.compiled.push(i)}test(e){for(let t=0,n=this.compiled.length;tthis.test(e)),t||{},this.options)}remove(e){return e.reduce(((e,t)=>(this.test(t)||e.push(t),e)),[])}}},2198:(e,t,n)=>{"use strict";n.d(t,{t:()=>o});var r=n(4629),o=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return(0,r.C6)(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){var e=this,t=e.hasError,n=e.thrownError,r=e._value;if(t)throw n;return this._throwIfClosed(),r},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(n(9092).B)},2403:(e,t,n)=>{"use strict";n.d(t,{XV:()=>o,MR:()=>i,fy:()=>u,oZ:()=>a,NV:()=>s,Q_:()=>c,C5:()=>l,GU:()=>f});var r=n(6827);const o=(0,r.jm)(r.XV),i=(0,r.jm)(r.MR),u=(0,r.jm)(r.fy),a=(0,r.jm)(r.oZ),s=(0,r.jm)(r.NV),c=(0,r.jm)(r.Q_),l=(0,r.jm)(r.C5),f=(0,r.jm)(r.GU)},2442:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7708),o=n(5307),i=n(5096),u=n(8071),a=n(4370);var s=n(1693);function c(e,t,n){return void 0===n&&(n=1/0),(0,s.T)(t)?c((function(n,i){return(0,r.T)((function(e,r){return t(n,e,i,r)}))((0,o.Tg)(e(n,i)))}),n):("number"==typeof t&&(n=t),(0,i.N)((function(t,r){return function(e,t,n,r,i,s,c,l){var f=[],h=0,d=0,p=!1,y=function(){!p||f.length||h||t.complete()},v=function(e){return h{"use strict";n.d(t,{B3:()=>u,DZ:()=>l,F5:()=>f,hu:()=>a,px:()=>p,qk:()=>i,to:()=>o});var r=n(744),o=(e=>(e.CLONE_ALL="CLONE_ALL",e.CLONE_INPUT="CLONE_INPUT",e.CLONE_OUTPUT="CLONE_OUTPUT",e.CLONE_OFF="CLONE_OFF",e))(o||{});class i{constructor(e,t,n,r=Date.now()){this._opts=e,this._root=t,this._local=n,this.timestamp=r,this.update(t,n)}static init(e,t,n){return e instanceof i?new i(e._opts,(0,r.gD)(e.root)?t:e.root,Object.assign({},e.local,n)):new i(e,t,n)}update(e,t){return this._root=e,this._local=t?Object.assign({},t,{variables:Object.assign({},this._local?.variables,t?.variables)}):t,this}getOptions(){return Object.freeze({...this._opts,context:s.from(this._opts.context)})}get root(){return this._root}get local(){return this._local}get idKey(){return this._opts.idKey}get collation(){return this._opts?.collation}get processingMode(){return this._opts?.processingMode||"CLONE_OFF"}get useStrictMode(){return this._opts?.useStrictMode}get scriptEnabled(){return this._opts?.scriptEnabled}get useGlobalContext(){return this._opts?.useGlobalContext}get hashFunction(){return this._opts?.hashFunction}get collectionResolver(){return this._opts?.collectionResolver}get jsonSchemaValidator(){return this._opts?.jsonSchemaValidator}get variables(){return this._opts?.variables}get context(){return this._opts?.context}}function u(e){return e instanceof i?e.getOptions():Object.freeze({idKey:"_id",scriptEnabled:!0,useStrictMode:!0,useGlobalContext:!0,processingMode:"CLONE_OFF",...e,context:e?.context?s.from(e?.context):s.init({})})}var a=(e=>(e.ACCUMULATOR="accumulator",e.EXPRESSION="expression",e.PIPELINE="pipeline",e.PROJECTION="projection",e.QUERY="query",e.WINDOW="window",e))(a||{});class s{constructor(e){this.operators={accumulator:{},expression:{},pipeline:{},projection:{},query:{},window:{}};for(const[t,n]of Object.entries(e))this.addOperators(t,n)}static init(e={}){return new s(e)}static from(e){return new s(e.operators)}addOperators(e,t){for(const[n,r]of Object.entries(t))this.getOperator(e,n)||(this.operators[e][n]=r);return this}addAccumulatorOps(e){return this.addOperators("accumulator",e)}addExpressionOps(e){return this.addOperators("expression",e)}addQueryOps(e){return this.addOperators("query",e)}addPipelineOps(e){return this.addOperators("pipeline",e)}addProjectionOps(e){return this.addOperators("projection",e)}addWindowOps(e){return this.addOperators("window",e)}getOperator(e,t){return e in this.operators&&this.operators[e][t]||null}}const c=s.init();function l(e,t){for(const[n,o]of Object.entries(t)){(0,r.vA)((0,r.Tn)(o)&&(0,r.Zo)(n),`'${n}' is not a valid operator`);const t=f(e,n,null);(0,r.vA)(!t||o===t,`${n} already exists for '${e}' operators. Cannot change operator function once registered.`)}switch(e){case"accumulator":c.addAccumulatorOps(t);break;case"expression":c.addExpressionOps(t);break;case"pipeline":c.addPipelineOps(t);break;case"projection":c.addProjectionOps(t);break;case"query":c.addQueryOps(t);break;case"window":c.addWindowOps(t)}}function f(e,t,n){const{context:r,useGlobalContext:o}=n||{},i=r?r.getOperator(e,t):null;return!i&&o?c.getOperator(e,t):i}const h={$$ROOT:(e,t,n)=>n.root,$$CURRENT:(e,t,n)=>e,$$REMOVE(e,t,n){},$$NOW:(e,t,n)=>new Date(n.timestamp)},d={$$KEEP:(e,t,n)=>e,$$PRUNE(e,t,n){},$$DESCEND(e,t,n){if(!(0,r.zy)(t,"$cond"))return e;let o;for(const[i,u]of Object.entries(e))if((0,r.Z4)(u)){if(u instanceof Array){const e=[];for(let o of u)(0,r.Gv)(o)&&(o=y(o,t,n.update(o))),(0,r.gD)(o)||e.push(o);o=e}else o=y(u,t,n.update(u));(0,r.gD)(o)?delete e[i]:e[i]=o}return e}};function p(e,t,n,o){const u=i.init(o,e);if(n=n||"",(0,r.Zo)(n)){const i=f("expression",n,o);if(i)return i(e,t,u);const a=f("accumulator",n,o);if(a)return e instanceof Array||(e=p(e,t,null,u),t=null),(0,r.vA)(e instanceof Array,`'${n}' target must be an array.`),a(e,t,u.update(null,u.local));throw new r.d8(`operator '${n}' is not registered`)}if((0,r.Kg)(t)&&t.length>0&&"$"===t[0]){if((0,r.zy)(d,t))return t;let n=u.root;const o=t.split(".");if((0,r.zy)(h,o[0]))n=h[o[0]](e,null,u),t=t.slice(o[0].length+1);else if("$$"===o[0].slice(0,2)){n=Object.assign({},u.variables,{this:e},u.local?.variables);const i=o[0].slice(2);(0,r.vA)((0,r.zy)(n,i),`Use of undefined variable: ${i}`),t=t.slice(2)}else t=t.slice(1);return""===t?n:(0,r.hd)(n,t)}if((0,r.cy)(t))return t.map((t=>p(e,t,null,u)));if((0,r.Gv)(t)){const n={};for(const[i,a]of Object.entries(t))if(n[i]=p(e,a,i,u),["expression","accumulator"].some((e=>!!f(e,i,o))))return(0,r.vA)(1===Object.keys(t).length,"Invalid aggregation expression '"+JSON.stringify(t)+"'"),n[i];return n}return t}function y(e,t,n){const o=p(e,t,null,n);return(0,r.zy)(d,o)?d[o](e,t,n):o}},3026:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,U:()=>u});var r=n(4629),o=n(1693);function i(e){return(0,r.AQ)(this,arguments,(function(){var t,n,o;return(0,r.YH)(this,(function(i){switch(i.label){case 0:t=e.getReader(),i.label=1;case 1:i.trys.push([1,,9,10]),i.label=2;case 2:return[4,(0,r.N3)(t.read())];case 3:return n=i.sent(),o=n.value,n.done?[4,(0,r.N3)(void 0)]:[3,5];case 4:return[2,i.sent()];case 5:return[4,(0,r.N3)(o)];case 6:return[4,i.sent()];case 7:return i.sent(),[3,2];case 8:return[3,10];case 9:return t.releaseLock(),[7];case 10:return[2]}}))}))}function u(e){return(0,o.T)(null==e?void 0:e.getReader)}},3356:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(5499);var o=n(235),i=n(9852);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{X:()=>l});var r=n(4629),o=n(5096),i=Array.isArray;var u=n(5499),a=n(235),s=n(9852);function c(){for(var e=[],t=0;t{"use strict";n.d(t,{T:()=>o});var r=n(1693);function o(e){return Symbol.asyncIterator&&(0,r.T)(null==e?void 0:e[Symbol.asyncIterator])}},3836:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}function o(e){var t=function(e,t){if("object"!=r(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t||"default");if("object"!=r(o))return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==r(t)?t:t+""}function i(e,t){for(var n=0;nu})},4134:(e,t,n)=>{"use strict";n.d(t,{c:()=>f});var r=n(8857),o=n(2258),i=n(8896),u=n(3887);function a(e){return 0===e.length?u.D:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var s=n(2236),c=n(1693),l=n(3004),f=function(){function e(e){e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var i,u=this,a=(i=e)&&i instanceof r.vU||function(e){return e&&(0,c.T)(e.next)&&(0,c.T)(e.error)&&(0,c.T)(e.complete)}(i)&&(0,o.Uv)(i)?e:new r.Ms(e,t,n);return(0,l.Y)((function(){var e=u,t=e.operator,n=e.source;a.add(t?t.call(a,n):n?u._subscribe(a):u._trySubscribe(a))})),a},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=h(t))((function(t,o){var i=new r.Ms({next:function(t){try{e(t)}catch(n){o(n),i.unsubscribe()}},error:o,complete:t});n.subscribe(i)}))},e.prototype._subscribe=function(e){var t;return null===(t=this.source)||void 0===t?void 0:t.subscribe(e)},e.prototype[i.s]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{h:()=>s});var r=n(5499),o=n(5307),i=new(n(4134).c)((function(e){return e.complete()}));var u=n(235),a=n(9852);function s(){for(var e=[],t=0;t{"use strict";n.d(t,{l:()=>r});var r="function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"},4429:(e,t,n)=>{"use strict";function r(e){return new TypeError("You provided "+(null!==e&&"object"==typeof e?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}n.d(t,{L:()=>r})},4799:(e,t,n)=>{"use strict";n.d(t,{x:()=>i});var r=n(4207),o=n(1693);function i(e){return(0,o.T)(null==e?void 0:e[r.l])}},4903:(e,t,n)=>{"use strict";n.d(t,{C2:()=>p,xF:()=>i});var r=n(2779),o=n(744);n(374);n(7681);const i=(e,t,n)=>{if((0,o.Im)(t)||!(0,o.Gv)(t))return e;let r=o.UD;const i=n.collation;return(0,o.Gv)(i)&&(0,o.Kg)(i.locale)&&(r=function(e){const t={sensitivity:u[e.strength||3],caseFirst:"off"===e.caseFirst?"false":e.caseFirst||"false",numeric:e.numericOrdering||!1,ignorePunctuation:"shifted"===e.alternate};!0===(e.caseLevel||!1)&&("base"===t.sensitivity&&(t.sensitivity="case"),"accent"===t.sensitivity&&(t.sensitivity="variant"));const n=new Intl.Collator(e.locale,t);return(e,t)=>{if(!(0,o.Kg)(e)||!(0,o.Kg)(t))return(0,o.UD)(e,t);const r=n.compare(e,t);return r<0?-1:r>0?1:0}}(i)),e.transform((e=>{const i=Object.keys(t);for(const u of i.reverse()){const i=(0,o.$z)(e,(e=>(0,o.hd)(e,u)),n.hashFunction),a=Array.from(i.keys()).sort(r);-1===t[u]&&a.reverse(),e=[],a.reduce(((e,t)=>(0,o.dj)(e,i.get(t))),e)}return e}))},u={1:"base",2:"accent",3:"variant"};n(1692);var a=n(6827);(0,a.fw)(a.GU);const s=(e,t)=>(n,i,u)=>{(0,o.vA)((0,o.cy)(i),`${e}: expression must be an array.`);const a=(0,r.px)(n,i,null,u);return a.some(o.gD)?null:((0,o.vA)(a.every(o.Et),`${e}: expression must evalue to array of numbers.`),t(a))};s("$bitAnd",(e=>e.reduce(((e,t)=>e&t),-1))),s("$bitOr",(e=>e.reduce(((e,t)=>e|t),0))),s("$bitXor",(e=>e.reduce(((e,t)=>e^t),0))),(0,a.fw)(a.XV),(0,a.fw)(a.MR),(0,a.fw)(a.fy),(0,a.fw)(a.NV),(0,a.fw)(a.Q_),(0,a.fw)(a.C5);const c=(e,t)=>{const n={};return e.split("").forEach(((e,r)=>n[e]=t*(r+1))),n};c("ABCDEFGHIKLM",1),c("NOPQRSTUVWXY",-1);const l={undefined:null,null:null,NaN:NaN,Infinity:new Error,"-Infinity":new Error};function f(e,t=l){const n=Object.assign({},l,t),i=new Set(Object.keys(n));return(t,u,a)=>{const s=(0,r.px)(t,u,null,a);if(i.has(`${s}`)){const t=n[`${s}`];if(t instanceof Error)throw new o.d8(`cannot apply $${e.name} to -inf, value must in (-inf,inf)`);return t}return e(s)}}f(Math.acos,{Infinity:1/0,0:new Error}),f(Math.acosh,{Infinity:1/0,0:new Error}),f(Math.asin),f(Math.asinh,{Infinity:1/0,"-Infinity":-1/0}),f(Math.atan),f(Math.atanh,{1:1/0,"-1":-1/0}),f(Math.cos),f(Math.cosh,{"-Infinity":1/0,Infinity:1/0});const h=Math.PI/180,d=(f((e=>e*h),{Infinity:1/0,"-Infinity":1/0}),180/Math.PI);f((e=>e*d),{Infinity:1/0,"-Infinity":-1/0}),f(Math.sin),f(Math.sinh,{"-Infinity":-1/0,Infinity:1/0}),f(Math.tan);Error;const p=(e,t,n)=>{if((0,o.Im)(t))return e;let i=Object.keys(t),u=!1;v(t,n);const a=n.idKey;if((0,o.RV)(i,a)){const e=t[a];0!==e&&!1!==e||(i=i.filter(o.KL.bind(null,[a])),u=0==i.length)}else i.push(a);const s=r.qk.init(n);return e.map((e=>y(e,t,s.update(e),i,u)))};function y(e,t,n,i,u){let a={},s=!1,c=!1;const l=[];u&&l.push(n.idKey);for(const f of i){let i;const u=t[f];if(f!==n.idKey&&(0,o.RV)([0,!1],u)&&(c=!0),f===n.idKey&&(0,o.Im)(u))i=e[f];else if((0,o.Kg)(u))i=(0,r.px)(e,u,f,n);else if((0,o.RV)([1,!0],u));else if(u instanceof Array)i=u.map((t=>{const i=(0,r.px)(e,t,null,n);return(0,o.gD)(i)?null:i}));else{if(!(0,o.Gv)(u)){l.push(f);continue}{const t=u,a=Object.keys(u),c=1==a.length?a[0]:"",l=(0,r.F5)(r.hu.PROJECTION,c,n);if(l)"$slice"===c?(0,o.eC)(t[c]).every(o.Et)?(i=l(e,t[c],f,n),s=!0):i=(0,r.px)(e,t,f,n):i=l(e,t[c],f,n);else if((0,o.Zo)(c))i=(0,r.px)(e,t[c],c,n);else if((0,o.zy)(e,f)){v(t,n);let r=e[f];r instanceof Array?i=r.map((e=>y(e,t,n,a,!1))):(r=(0,o.Gv)(r)?r:e,i=y(r,t,n,a,!1))}else i=(0,r.px)(e,u,null,n)}}const h=(0,o.Rm)(e,f,{preserveMissing:!0});void 0!==h&&(0,o.h1)(a,h,{flatten:!0}),(0,o.KL)([0,1,!1,!0],u)&&(void 0===i?(0,o.yT)(a,f,{descendArray:!0}):(0,o.KY)(a,f,i))}if((0,o.B2)(a),(s||c||u)&&(a=(0,o.dj)({},e,a),l.length>0))for(const r of l)(0,o.yT)(a,r,{descendArray:!0});return a}function v(e,t){const n=[!1,!1];for(const[r,i]of Object.entries(e)){if(r===t?.idKey)return;0===i||!1===i?n[0]=!0:1!==i&&!0!==i||(n[1]=!0),(0,o.vA)(!(n[0]&&n[1]),"Projection cannot have a mix of inclusion and exclusion.")}}},5307:(e,t,n)=>{"use strict";n.d(t,{Tg:()=>y});var r=n(4629),o=n(9739),i=n(5796),u=n(4134),a=n(1446),s=n(3819),c=n(4429),l=n(4799),f=n(3026),h=n(1693),d=n(6712),p=n(8896);function y(e){if(e instanceof u.c)return e;if(null!=e){if((0,a.l)(e))return b=e,new u.c((function(e){var t=b[p.s]();if((0,h.T)(t.subscribe))return t.subscribe(e);throw new TypeError("Provided object does not correctly implement Symbol.observable")}));if((0,o.X)(e))return m=e,new u.c((function(e){for(var t=0;t{"use strict";n.d(t,{U:()=>i});var r=n(2442),o=n(3887);function i(e){return void 0===e&&(e=1/0),(0,r.Z)(o.D,e)}},5525:(e,t,n)=>{"use strict";n.d(t,{p4:()=>r});class r{ttl;map=new Map;_to=!1;constructor(e){this.ttl=e}has(e){return this.map.has(e)}add(e){this.map.set(e,o()),this._to||(this._to=!0,setTimeout((()=>{this._to=!1,function(e){const t=o()-e.ttl,n=e.map[Symbol.iterator]();for(;;){const r=n.next().value;if(!r)return;const o=r[0];if(!(r[1]{"use strict";n.d(t,{y:()=>o});var r=n(1693);function o(e){return(0,r.T)(null==e?void 0:e.then)}},6114:(e,t,n)=>{"use strict";n.d(t,{kC:()=>q,Cs:()=>B});const r=e=>{e.previousResults.unshift(e.changeEvent.doc),e.keyDocumentMap&&e.keyDocumentMap.set(e.changeEvent.id,e.changeEvent.doc)},o=e=>{e.previousResults.push(e.changeEvent.doc),e.keyDocumentMap&&e.keyDocumentMap.set(e.changeEvent.id,e.changeEvent.doc)},i=e=>{const t=e.previousResults.shift();e.keyDocumentMap&&t&&e.keyDocumentMap.delete(t[e.queryParams.primaryKey])},u=e=>{const t=e.previousResults.pop();e.keyDocumentMap&&t&&e.keyDocumentMap.delete(t[e.queryParams.primaryKey])},a=e=>{e.keyDocumentMap&&e.keyDocumentMap.delete(e.changeEvent.id);const t=e.queryParams.primaryKey,n=e.previousResults;for(let r=0;r{const t=e.changeEvent.id,n=e.changeEvent.doc;if(e.keyDocumentMap){if(e.keyDocumentMap.has(t))return;e.keyDocumentMap.set(t,n)}else{if(e.previousResults.find((n=>n[e.queryParams.primaryKey]===t)))return}!function(e,t,n,r){var o,i=e.length,u=i-1,a=0;if(0===i)return e.push(t),0;for(;r<=u;)n(o=e[a=r+(u-r>>1)],t)<=0?r=a+1:u=a-1;n(o,t)<=0&&a++,e.splice(a,0,t)}(e.previousResults,n,e.queryParams.sortComparator,0)},c=["doNothing","insertFirst","insertLast","removeFirstItem","removeLastItem","removeFirstInsertLast","removeLastInsertFirst","removeFirstInsertFirst","removeLastInsertLast","removeExisting","replaceExisting","alwaysWrong","insertAtSortPosition","removeExistingAndInsertAtSortPosition","runFullQueryAgain","unknownAction"],l={doNothing:e=>{},insertFirst:r,insertLast:o,removeFirstItem:i,removeLastItem:u,removeFirstInsertLast:e=>{i(e),o(e)},removeLastInsertFirst:e=>{u(e),r(e)},removeFirstInsertFirst:e=>{i(e),r(e)},removeLastInsertLast:e=>{u(e),o(e)},removeExisting:a,replaceExisting:e=>{const t=e.changeEvent.doc,n=e.queryParams.primaryKey,r=e.previousResults;for(let o=0;o{const t={_id:"wrongHuman"+(new Date).getTime()};e.previousResults.length=0,e.previousResults.push(t),e.keyDocumentMap&&(e.keyDocumentMap.clear(),e.keyDocumentMap.set(t._id,t))},insertAtSortPosition:s,removeExistingAndInsertAtSortPosition:e=>{a(e),s(e)},runFullQueryAgain:e=>{throw new Error("Action runFullQueryAgain must be implemented by yourself")},unknownAction:e=>{throw new Error("Action unknownAction should never be called")}};!function(e=6){let t="";const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let r=0;r!!e.queryParams.limit,m=e=>1===e.queryParams.limit,b=e=>!!(e.queryParams.skip&&e.queryParams.skip>0),g=e=>"DELETE"===e.changeEvent.operation,w=e=>"INSERT"===e.changeEvent.operation,_=e=>"UPDATE"===e.changeEvent.operation,x=e=>v(e)&&e.previousResults.length>=e.queryParams.limit,k=e=>{const t=e.queryParams.sortFields,n=e.changeEvent.previous,r=e.changeEvent.doc;if(!r)return!1;if(!n)return!0;for(let o=0;o{const t=e.changeEvent.id;if(e.keyDocumentMap){return e.keyDocumentMap.has(t)}{const n=e.queryParams.primaryKey,r=e.previousResults;for(let e=0;e{const t=e.previousResults[0];return!(!t||t[e.queryParams.primaryKey]!==e.changeEvent.id)},P=e=>{const t=d(e.previousResults);return!(!t||t[e.queryParams.primaryKey]!==e.changeEvent.id)},S=e=>{const t=e.changeEvent.previous;if(!t)return!1;const n=e.previousResults[0];if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)<0},j=e=>{const t=e.changeEvent.previous;if(!t)return!1;const n=d(e.previousResults);if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)>0},A=e=>{const t=e.changeEvent.doc;if(!t)return!1;const n=e.previousResults[0];if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)<0},C=e=>{const t=e.changeEvent.doc;if(!t)return!1;const n=d(e.previousResults);if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)>0},I=e=>{const t=e.changeEvent.previous;return!!t&&e.queryParams.queryMatcher(t)},K=e=>{const t=e.changeEvent.doc;if(!t)return!1;return e.queryParams.queryMatcher(t)},T=e=>0===e.previousResults.length,M={0:w,1:_,2:g,3:v,4:m,5:b,6:T,7:x,8:E,9:P,10:k,11:O,12:S,13:j,14:A,15:C,16:I,17:K};let D;function R(){return D||(D=function(e){const t=new Map,n=2+2*parseInt(e.charAt(0)+e.charAt(1),10),r=f(e.substring(2,n),2);for(let s=0;sfunction(e,t,n){let r=e,o=e.l;for(;;){if(r=r[t[o](n)?"1":"0"],"number"==typeof r||"string"==typeof r)return r;o=r.l}}(R(),M,e);function q(e){const t=N(e);return c[t]}function B(e,t,n,r,o){return(0,l[e])({queryParams:t,changeEvent:n,previousResults:r,keyDocumentMap:o}),r}},6343:(e,t,n)=>{"use strict";function r(e){return r=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},r(e)}n.d(t,{A:()=>u});var o=n(1576);function i(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(i=function(){return!!e})()}function u(e){var t="function"==typeof Map?new Map:void 0;return u=function(e){if(null===e||!function(e){try{return-1!==Function.toString.call(e).indexOf("[native code]")}catch(t){return"function"==typeof e}}(e))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return function(e,t,n){if(i())return Reflect.construct.apply(null,arguments);var r=[null];r.push.apply(r,t);var u=new(e.bind.apply(e,r));return n&&(0,o.A)(u,n.prototype),u}(e,arguments,r(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),(0,o.A)(n,e)},u(e)}},6823:(e,t,n)=>{"use strict";n.d(t,{P:()=>o,T:()=>i});var r=n(6827);const o=(0,r.jm)(r.P),i=(0,r.jm)(r.TU)},6827:(e,t,n)=>{"use strict";n.d(t,{C5:()=>c,GU:()=>f,Gd:()=>g,Ig:()=>w,Jy:()=>x,MR:()=>p,NV:()=>h,P:()=>b,Pp:()=>v,Q_:()=>d,TU:()=>j,WP:()=>m,XV:()=>s,fw:()=>a,fy:()=>y,jm:()=>u,oZ:()=>l});var r=n(2779),o=n(1692),i=n(744);function u(e){const t=(t,n,r)=>{const o={unwrapArray:!0},u=Math.max(1,t.split(".").length-1);return a=>{const s=(0,i.hd)(a,t,o);return e(s,n,{...r,depth:u})}};return t.op="query",t}function a(e){return(t,n,o)=>{const i=(0,r.px)(t,n,null,o);return e(...i)}}function s(e,t,n){if((0,i.n4)(e,t))return!0;if((0,i.gD)(e)&&(0,i.gD)(t))return!0;if(e instanceof Array){const r=i.n4.bind(null,t);return e.some(r)||(0,i.Bq)(e,n?.depth).some(r)}return!1}function c(e,t,n){return!s(e,t,n)}function l(e,t,n){return(0,i.gD)(e)?t.some((e=>null===e)):(0,i.E$)([(0,i.eC)(e),t],n?.hashFunction).length>0}function f(e,t,n){return!l(e,t,n)}function h(e,t,n){return A(e,t,((e,t)=>(0,i.UD)(e,t)<0))}function d(e,t,n){return A(e,t,((e,t)=>(0,i.UD)(e,t)<=0))}function p(e,t,n){return A(e,t,((e,t)=>(0,i.UD)(e,t)>0))}function y(e,t,n){return A(e,t,((e,t)=>(0,i.UD)(e,t)>=0))}function v(e,t,n){return(0,i.eC)(e).some((e=>2===t.length&&e%t[0]===t[1]))}function m(e,t,n){const r=(0,i.eC)(e),o=e=>(0,i.Kg)(e)&&(0,i.vN)(t.exec(e),n?.useStrictMode);return r.some(o)||(0,i.Bq)(r,1).some(o)}function b(e,t,n){return(!1===t||0===t)&&void 0===e||(!0===t||1===t)&&void 0!==e}function g(e,t,n){if(!((0,i.cy)(e)&&(0,i.cy)(t)&&e.length&&t.length))return!1;let r=!0;for(const o of t){if(!r)break;r=(0,i.Gv)(o)&&(0,i.RV)(Object.keys(o),"$elemMatch")?x(e,o.$elemMatch,n):o instanceof RegExp?e.some((e=>"string"==typeof e&&o.test(e))):e.some((e=>(0,i.n4)(o,e)))}return r}function w(e,t,n){return Array.isArray(e)&&e.length===t}function _(e){return(0,i.Zo)(e)&&-1===["$and","$or","$nor"].indexOf(e)}function x(e,t,n){if((0,i.cy)(e)&&!(0,i.Im)(e)){let r=e=>e,i=t;Object.keys(t).every(_)&&(i={temp:t},r=e=>({temp:e}));const u=new o.X(i,n);for(let t=0,n=e.length;tnull===e,O=e=>(0,i.Et)(e)&&e>=i.R&&e<=i.Hq&&-1===e.toString().indexOf("."),E=e=>(0,i.Et)(e)&&e>=i.oU&&e<=i.W_&&-1===e.toString().indexOf("."),P={array:i.cy,bool:i.Lm,boolean:i.Lm,date:i.$P,decimal:i.Et,double:i.Et,int:O,long:E,number:i.Et,null:k,object:i.Gv,regex:i.gd,regexp:i.gd,string:i.Kg,undefined:i.gD,function:e=>{throw new i.d8("unsupported type key `function`.")},1:i.Et,2:i.Kg,3:i.Gv,4:i.cy,6:i.gD,8:i.Lm,9:i.$P,10:k,11:i.gd,16:O,18:E,19:i.Et};function S(e,t,n){const r=P[t];return!!r&&r(e)}function j(e,t,n){return Array.isArray(t)?t.findIndex((t=>S(e,t)))>=0:S(e,t)}function A(e,t,n){return(0,i.eC)(e).some((e=>(0,i.Pw)(e)===(0,i.Pw)(t)&&n(e,t)))}},6950:(e,t,n)=>{"use strict";n.d(t,{Jy:()=>o,Ig:()=>i});var r=n(6827);(0,r.jm)(r.Gd);const o=(0,r.jm)(r.Jy),i=(0,r.jm)(r.Ig)},7329:(e,t,n)=>{"use strict";n.d(t,{cf:()=>i});var r=n(8900);const o=Symbol.for("Dexie"),i=globalThis[o]||(globalThis[o]=r);if(r.semVer!==i.semVer)throw new Error(`Two different versions of Dexie loaded in the same app: ${r.semVer} and ${i.semVer}`);const{liveQuery:u,mergeRanges:a,rangesOverlap:s,RangeSet:c,cmp:l,Entity:f,PropModSymbol:h,PropModification:d,replacePrefix:p,add:y,remove:v}=i},7635:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});var r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this._parallels=e||1,this._qC=0,this._iC=new Set,this._lHN=0,this._hPM=new Map,this._pHM=new Map};function o(e,t){if(t){if(t._timeoutObj&&clearTimeout(t._timeoutObj),e._pHM.has(t)){var n=e._pHM.get(t);e._hPM.delete(n),e._pHM.delete(t)}e._iC.delete(t)}}function i(e){e._tryIR||0===e._iC.size||(e._tryIR=!0,setTimeout((function(){e.isIdle()?setTimeout((function(){e.isIdle()?(!function(e){0!==e._iC.size&&(e._iC.values().next().value._manRes(),setTimeout((function(){return i(e)}),0))}(e),e._tryIR=!1):e._tryIR=!1}),0):e._tryIR=!1}),0))}r.prototype={isIdle:function(){return this._qC{"use strict";n.d(t,{u:()=>u});var r=n(2779),o=n(374),i=n(744);class u{constructor(e,t){this.pipeline=e,this.options=(0,r.B3)(t)}stream(e){let t=(0,o.dF)(e);const n=this.options.processingMode;n!=r.to.CLONE_ALL&&n!=r.to.CLONE_INPUT||t.map(i.mg);const u=new Array;if(!(0,i.Im)(this.pipeline))for(const o of this.pipeline){const e=Object.keys(o),n=e[0],a=(0,r.F5)(r.hu.PIPELINE,n,this.options);(0,i.vA)(1===e.length&&!!a,`invalid pipeline operator ${n}`),u.push(n),t=a(t,o[n],this.options)}return(n==r.to.CLONE_OUTPUT||n==r.to.CLONE_ALL&&(0,i.E$)([["$group","$unwind"],u]).length)&&t.map(i.mg),t}run(e){return this.stream(e).value()}}},7705:(e,t,n)=>{"use strict";n.d(t,{a6:()=>i,q3:()=>a,En:()=>s,sU:()=>u});var r=n(1692),o=n(744);const i=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression: $and expects value to be an Array.");const i=t.map((e=>new r.X(e,n)));return e=>i.every((t=>t.test(e)))},u=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression. $or expects value to be an Array");const i=t.map((e=>new r.X(e,n)));return e=>i.some((t=>t.test(e)))},a=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression. $nor expects value to be an array.");const r=u("$or",t,n);return e=>!r(e)},s=(e,t,n)=>{const i={};i[e]=(0,o.S8)(t);const u=new r.X(i,n);return e=>!u.test(e)}},8071:(e,t,n)=>{"use strict";function r(e,t,n,r,o){void 0===r&&(r=0),void 0===o&&(o=!1);var i=t.schedule((function(){n(),o?e.add(this.schedule(null,r)):this.unsubscribe()}),r);if(e.add(i),!o)return i}n.d(t,{N:()=>r})},8146:(e,t,n)=>{"use strict";n.d(t,{p:()=>i});var r=n(5096),o=n(4370);function i(e,t){return(0,r.N)((function(n,r){var i=0;n.subscribe((0,o._)(r,(function(n){return e.call(t,n,i++)&&r.next(n)})))}))}},8609:(e,t,n)=>{"use strict";n.d(t,{t:()=>f});var r=n(4629),o=n(9092),i={now:function(){return(i.delegate||Date).now()},delegate:void 0},u=function(e){function t(t,n,r){void 0===t&&(t=1/0),void 0===n&&(n=1/0),void 0===r&&(r=i);var o=e.call(this)||this;return o._bufferSize=t,o._windowTime=n,o._timestampProvider=r,o._buffer=[],o._infiniteTimeWindow=!0,o._infiniteTimeWindow=n===1/0,o._bufferSize=Math.max(1,t),o._windowTime=Math.max(1,n),o}return(0,r.C6)(t,e),t.prototype.next=function(t){var n=this,r=n.isStopped,o=n._buffer,i=n._infiniteTimeWindow,u=n._timestampProvider,a=n._windowTime;r||(o.push(t),!i&&o.push(u.now()+a)),this._trimBuffer(),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){this._throwIfClosed(),this._trimBuffer();for(var t=this._innerSubscribe(e),n=this._infiniteTimeWindow,r=this._buffer.slice(),o=0;o0&&(t=new s.Ms({next:function(e){return b.next(e)},error:function(e){p=!0,y(),r=l(v,i,e),b.error(e)},complete:function(){h=!0,y(),r=l(v,f),b.complete()}}),(0,a.Tg)(e).subscribe(t))}))(e)}}({connector:function(){return new u(h,t,n)},resetOnError:!0,resetOnComplete:!1,resetOnRefCountZero:d})}},8896:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r="function"==typeof Symbol&&Symbol.observable||"@@observable"},8900:function(e,t,n){e.exports=function(){"use strict";var e=function(t,n){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(t,n)},t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n.",et="String expected.",tt=[],nt="__dbnames",rt="readonly",ot="readwrite";function it(e,t){return e?t?function(){return e.apply(this,arguments)&&t.apply(this,arguments)}:e:t}var ut={type:3,lower:-1/0,lowerOpen:!1,upper:[[]],upperOpen:!1};function at(e){return"string"!=typeof e||/\./.test(e)?function(e){return e}:function(t){return void 0===t[e]&&e in t&&delete(t=A(t))[e],t}}function st(){throw W.Type()}function ct(e,t){try{var n=lt(e),r=lt(t);if(n!==r)return"Array"===n?1:"Array"===r?-1:"binary"===n?1:"binary"===r?-1:"string"===n?1:"string"===r?-1:"Date"===n?1:"Date"!==r?NaN:-1;switch(n){case"number":case"Date":case"string":return tn+u&&o(n+h)}))}))}var i=vt(n)&&n.limit===1/0&&("function"!=typeof e||e===St)&&{index:n.index,range:n.range};return o(0).then((function(){if(0=o}))).length?(t.forEach((function(e){c.push((function(){var t=l,n=e._cfg.dbschema;hn(r,t,s),hn(r,n,s),l=r._dbSchema=n;var u=an(t,n);u.add.forEach((function(e){sn(s,e[0],e[1].primKey,e[1].indexes)})),u.change.forEach((function(e){if(e.recreate)throw new W.Upgrade("Not yet support for changing primary key");var t=s.objectStore(e.name);e.add.forEach((function(e){return ln(t,e)})),e.change.forEach((function(e){t.deleteIndex(e.name),ln(t,e)})),e.del.forEach((function(e){return t.deleteIndex(e)}))}));var c=e._cfg.contentUpgrade;if(c&&e._cfg.version>o){en(r,s),a._memoizedTables={};var f=k(n);u.del.forEach((function(e){f[e]=t[e]})),nn(r,[r.Transaction.prototype]),tn(r,[r.Transaction.prototype],i(f),f),a.schema=f;var h,d=N(c);return d&&$e(),u=xe.follow((function(){var e;(h=c(a))&&d&&(e=Ue.bind(null,null),h.then(e,e))})),h&&"function"==typeof h.then?xe.resolve(h):u.then((function(){return h}))}})),c.push((function(t){var n,o,i=e._cfg.dbschema;n=i,o=t,[].slice.call(o.db.objectStoreNames).forEach((function(e){return null==n[e]&&o.db.deleteObjectStore(e)})),nn(r,[r.Transaction.prototype]),tn(r,[r.Transaction.prototype],r._storeNames,r._dbSchema),a.schema=r._dbSchema})),c.push((function(t){r.idbdb.objectStoreNames.contains("$meta")&&(Math.ceil(r.idbdb.version/10)===e._cfg.version?(r.idbdb.deleteObjectStore("$meta"),delete r._dbSchema.$meta,r._storeNames=r._storeNames.filter((function(e){return"$meta"!==e}))):t.objectStore("$meta").put(e._cfg.version,"version"))}))})),function e(){return c.length?xe.resolve(c.shift()(a.idbtrans)).then(e):xe.resolve()}().then((function(){cn(l,s)}))):xe.resolve();var r,o,a,s,c,l})).catch(a)):(i(o).forEach((function(e){sn(n,e,o[e].primKey,o[e].indexes)})),en(e,n),void xe.follow((function(){return e.on.populate.fire(u)})).catch(a));var r,c}))}function un(e,t){cn(e._dbSchema,t),t.db.version%10!=0||t.objectStoreNames.contains("$meta")||t.db.createObjectStore("$meta").add(Math.ceil(t.db.version/10-1),"version");var n=fn(0,e.idbdb,t);hn(e,e._dbSchema,t);for(var r=0,o=an(n,e._dbSchema).change;rMath.pow(2,62)?0:r.oldVersion,h=r<1,e.idbdb=d.result,u&&un(e,f),on(e,r/10,f,c))}),c),d.onsuccess=Me((function(){f=null;var n,a,c,p,y,v=e.idbdb=d.result,b=m(v.objectStoreNames);if(0t.limit?n.length=t.limit:e.length===t.limit&&n.length=r.limit&&(!r.values||e.req.values)&&Qn(e.req.query.range,r.query.range)})),!1,o,i];case"count":return u=i.find((function(e){return Hn(e.req.query.range,r.query.range)})),[u,!!u,o,i]}}(n,r,"query",e),s=a[0],c=a[1],l=a[2],f=a[3];return s&&c?s.obsSet=e.obsSet:(c=o.query(e).then((function(e){var n=e.result;if(s&&(s.res=n),t){for(var r=0,o=n.length;r{"use strict";n.d(t,{B:()=>c});var r=n(4629),o=n(4134),i=n(2258),u=(0,n(5383).L)((function(e){return function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"}})),a=n(34),s=n(3004),c=function(e){function t(){var t=e.call(this)||this;return t.closed=!1,t.currentObservers=null,t.observers=[],t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return(0,r.C6)(t,e),t.prototype.lift=function(e){var t=new l(this,this);return t.operator=e,t},t.prototype._throwIfClosed=function(){if(this.closed)throw new u},t.prototype.next=function(e){var t=this;(0,s.Y)((function(){var n,o;if(t._throwIfClosed(),!t.isStopped){t.currentObservers||(t.currentObservers=Array.from(t.observers));try{for(var i=(0,r.Ju)(t.currentObservers),u=i.next();!u.done;u=i.next()){u.value.next(e)}}catch(a){n={error:a}}finally{try{u&&!u.done&&(o=i.return)&&o.call(i)}finally{if(n)throw n.error}}}}))},t.prototype.error=function(e){var t=this;(0,s.Y)((function(){if(t._throwIfClosed(),!t.isStopped){t.hasError=t.isStopped=!0,t.thrownError=e;for(var n=t.observers;n.length;)n.shift().error(e)}}))},t.prototype.complete=function(){var e=this;(0,s.Y)((function(){if(e._throwIfClosed(),!e.isStopped){e.isStopped=!0;for(var t=e.observers;t.length;)t.shift().complete()}}))},t.prototype.unsubscribe=function(){this.isStopped=this.closed=!0,this.observers=this.currentObservers=null},Object.defineProperty(t.prototype,"observed",{get:function(){var e;return(null===(e=this.observers)||void 0===e?void 0:e.length)>0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(t){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,t)},t.prototype._subscribe=function(e){return this._throwIfClosed(),this._checkFinalizedStatuses(e),this._innerSubscribe(e)},t.prototype._innerSubscribe=function(e){var t=this,n=this,r=n.hasError,o=n.isStopped,u=n.observers;return r||o?i.Kn:(this.currentObservers=null,u.push(e),new i.yU((function(){t.currentObservers=null,(0,a.o)(u,e)})))},t.prototype._checkFinalizedStatuses=function(e){var t=this,n=t.hasError,r=t.thrownError,o=t.isStopped;n?e.error(r):o&&e.complete()},t.prototype.asObservable=function(){var e=new o.c;return e.source=this,e},t.create=function(e,t){return new l(e,t)},t}(o.c),l=function(e){function t(t,n){var r=e.call(this)||this;return r.destination=t,r.source=n,r}return(0,r.C6)(t,e),t.prototype.next=function(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.next)||void 0===n||n.call(t,e)},t.prototype.error=function(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.error)||void 0===n||n.call(t,e)},t.prototype.complete=function(){var e,t;null===(t=null===(e=this.destination)||void 0===e?void 0:e.complete)||void 0===t||t.call(e)},t.prototype._subscribe=function(e){var t,n;return null!==(n=null===(t=this.source)||void 0===t?void 0:t.subscribe(e))&&void 0!==n?n:i.Kn},t}(c)},9739:(e,t,n)=>{"use strict";n.d(t,{X:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9852:(e,t,n)=>{"use strict";n.d(t,{H:()=>_});var r=n(5307),o=n(8071),i=n(5096),u=n(4370);function a(e,t){return void 0===t&&(t=0),(0,i.N)((function(n,r){n.subscribe((0,u._)(r,(function(n){return(0,o.N)(r,e,(function(){return r.next(n)}),t)}),(function(){return(0,o.N)(r,e,(function(){return r.complete()}),t)}),(function(n){return(0,o.N)(r,e,(function(){return r.error(n)}),t)})))}))}function s(e,t){return void 0===t&&(t=0),(0,i.N)((function(n,r){r.add(e.schedule((function(){return n.subscribe(r)}),t))}))}var c=n(4134);var l=n(4207),f=n(1693);function h(e,t){if(!e)throw new Error("Iterable cannot be null");return new c.c((function(n){(0,o.N)(n,t,(function(){var r=e[Symbol.asyncIterator]();(0,o.N)(n,t,(function(){r.next().then((function(e){e.done?n.complete():n.next(e.value)}))}),0,!0)}))}))}var d=n(1446),p=n(5796),y=n(9739),v=n(4799),m=n(3819),b=n(4429),g=n(3026);function w(e,t){if(null!=e){if((0,d.l)(e))return function(e,t){return(0,r.Tg)(e).pipe(s(t),a(t))}(e,t);if((0,y.X)(e))return function(e,t){return new c.c((function(n){var r=0;return t.schedule((function(){r===e.length?n.complete():(n.next(e[r++]),n.closed||this.schedule())}))}))}(e,t);if((0,p.y)(e))return function(e,t){return(0,r.Tg)(e).pipe(s(t),a(t))}(e,t);if((0,m.T)(e))return h(e,t);if((0,v.x)(e))return function(e,t){return new c.c((function(n){var r;return(0,o.N)(n,t,(function(){r=e[l.l](),(0,o.N)(n,t,(function(){var e,t,o;try{t=(e=r.next()).value,o=e.done}catch(i){return void n.error(i)}o?n.complete():n.next(t)}),0,!0)})),function(){return(0,f.T)(null==r?void 0:r.return)&&r.return()}}))}(e,t);if((0,g.U)(e))return function(e,t){return h((0,g.C)(e),t)}(e,t)}throw(0,b.L)(e)}function _(e,t){return t?w(e,t):(0,r.Tg)(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/1db64337.f3f8abcd.js b/docs/assets/js/1db64337.f3f8abcd.js new file mode 100644 index 00000000000..790e4c9493d --- /dev/null +++ b/docs/assets/js/1db64337.f3f8abcd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[8413],{0:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>m,contentTitle:()=>y,default:()=>x,frontMatter:()=>b,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"overview","title":"RxDB Docs","description":"RxDB Documentation Overview","source":"@site/docs/overview.md","sourceDirName":".","slug":"/overview.html","permalink":"/overview.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"RxDB Docs","slug":"overview.html","description":"RxDB Documentation Overview"},"sidebar":"tutorialSidebar","next":{"title":"\ud83d\ude80 Quickstart","permalink":"/quickstart.html"}}');var l=a(4848),i=a(8453),o=a(8653);const c={tutorialSidebar:[{type:"category",label:"Getting Started with RxDB",collapsed:!1,items:[{type:"doc",id:"overview",label:"Overview"},"quickstart","install","dev-mode","tutorials/typescript"]},{type:"category",label:"Core Entities",collapsed:!1,items:[{type:"doc",id:"rx-database",label:"RxDatabase"},{type:"doc",id:"rx-schema",label:"RxSchema"},{type:"doc",id:"rx-collection",label:"RxCollection"},{type:"doc",id:"rx-document",label:"RxDocument"},{type:"doc",id:"rx-query",label:"RxQuery"}]},{type:"category",label:"\ud83d\udcbe Storages",items:[{type:"doc",id:"rx-storage",label:"RxStorage Overview"},{type:"doc",id:"rx-storage-dexie",label:"Dexie.js"},{type:"doc",id:"rx-storage-indexeddb",label:"IndexedDB \ud83d\udc51"},{type:"doc",id:"rx-storage-opfs",label:"OPFS \ud83d\udc51"},{type:"doc",id:"rx-storage-memory",label:"Memory"},{type:"doc",id:"rx-storage-sqlite",label:"SQLite \ud83d\udc51"},{type:"doc",id:"rx-storage-filesystem-node",label:"Filesystem Node \ud83d\udc51"},{type:"doc",id:"rx-storage-mongodb",label:"MongoDB"},{type:"doc",id:"rx-storage-denokv",label:"DenoKV"},{type:"doc",id:"rx-storage-foundationdb",label:"FoundationDB"}]},{type:"category",label:"Storage Wrappers",items:[{type:"doc",id:"schema-validation",label:"Schema Validation"},{type:"doc",id:"encryption",label:"Encryption"},{type:"doc",id:"key-compression",label:"Key Compression"},{type:"doc",id:"logger",label:"Logger \ud83d\udc51"},{type:"doc",id:"rx-storage-remote",label:"Remote RxStorage"},{type:"doc",id:"rx-storage-worker",label:"Worker RxStorage \ud83d\udc51"},{type:"doc",id:"rx-storage-shared-worker",label:"SharedWorker RxStorage \ud83d\udc51"},{type:"doc",id:"rx-storage-memory-mapped",label:"Memory Mapped RxStorage \ud83d\udc51"},{type:"doc",id:"rx-storage-sharding",label:"Sharding \ud83d\udc51"},{type:"doc",id:"rx-storage-localstorage-meta-optimizer",label:"Localstorage Meta Optimizer \ud83d\udc51"},{type:"doc",id:"electron",label:"Electron"}]},{type:"category",label:"\ud83d\udd04 Replication",items:["replication",{type:"doc",id:"replication-http",label:"HTTP Replication"},{type:"doc",id:"replication-server",label:"RxServer Replication"},{type:"doc",id:"replication-graphql",label:"GraphQL Replication"},{type:"doc",id:"replication-websocket",label:"WebSocket Replication"},{type:"doc",id:"replication-couchdb",label:"CouchDB Replication"},{type:"doc",id:"replication-webrtc",label:"WebRTC P2P Replication"},{type:"doc",id:"replication-firestore",label:"Firestore Replication"},{type:"doc",id:"replication-nats",label:"NATS Replication"}]},{type:"category",label:"Server",items:[{type:"doc",id:"rx-server",label:"RxServer"},{type:"doc",id:"rx-server-scaling",label:"RxServer Scaling"}]},{type:"category",label:"How RxDB works",items:[{type:"doc",id:"transactions-conflicts-revisions",label:"Transactions Conflicts Revisions"},{type:"doc",id:"query-cache",label:"Query Cache"},{type:"doc",id:"plugins",label:"Creating Plugins"},{type:"doc",id:"errors",label:"Errors"}]},{type:"category",label:"Advanced Features",items:[{type:"category",label:"Migration",items:[{type:"doc",id:"migration-schema",label:"Schema Migration"},{type:"doc",id:"migration-storage",label:"Storage Migration"}]},{type:"doc",id:"rx-attachment",label:"Attachments"},{type:"doc",id:"rx-pipeline",label:"RxPipelines"},{type:"doc",id:"reactivity",label:"Custom Reactivity"},{type:"doc",id:"rx-state",label:"RxState"},{type:"doc",id:"rx-local-document",label:"Local Documents"},{type:"doc",id:"cleanup",label:"Cleanup"},{type:"doc",id:"backup",label:"Backup"},{type:"doc",id:"leader-election",label:"Leader Election"},{type:"doc",id:"middleware",label:"Middleware"},{type:"doc",id:"crdt",label:"CRDT"},{type:"doc",id:"population",label:"Population"},{type:"doc",id:"orm",label:"ORM"},{type:"doc",id:"fulltext-search",label:"Fulltext Search \ud83d\udc51"},{type:"doc",id:"articles/javascript-vector-database",label:"Vector Database"},{type:"doc",id:"query-optimizer",label:"Query Optimizer \ud83d\udc51"},{type:"doc",id:"third-party-plugins",label:"Third Party Plugins"}]},{type:"category",label:"Performance",items:[{type:"doc",id:"rx-storage-performance",label:"RxStorage Performance"},{type:"doc",id:"nosql-performance-tips",label:"NoSQL Performance Tips"},{type:"doc",id:"slow-indexeddb",label:"Slow IndexedDB"},{type:"doc",id:"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm",label:"LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite"}]},{type:"category",label:"Releases",items:[{type:"doc",id:"releases/16.0.0",label:"16.0.0"},{type:"doc",id:"releases/15.0.0",label:"15.0.0"},{type:"doc",id:"releases/14.0.0",label:"14.0.0"},{type:"doc",id:"releases/13.0.0",label:"13.0.0"},{type:"doc",id:"releases/12.0.0",label:"12.0.0"},{type:"doc",id:"releases/11.0.0",label:"11.0.0"},{type:"doc",id:"releases/10.0.0",label:"10.0.0"},{type:"doc",id:"releases/9.0.0",label:"9.0.0"},{type:"doc",id:"releases/8.0.0",label:"8.0.0"}]},{type:"category",label:"Articles",items:["offline-first","downsides-of-offline-first","why-nosql","nodejs-database","alternatives","react-native-database","articles/angular-database","articles/browser-database","articles/browser-storage","articles/data-base","articles/embedded-database","articles/flutter-database","articles/frontend-database","articles/in-memory-nosql-database","articles/ionic-database","articles/ionic-storage","articles/json-database","articles/websockets-sse-polling-webrtc-webtransport","articles/localstorage","articles/mobile-database","articles/progressive-web-app-database","articles/react-database","articles/realtime-database","articles/angular-indexeddb","articles/react-indexeddb","capacitor-database","electron-database","articles/optimistic-ui","articles/local-database","articles/react-native-encryption","articles/vue-database","articles/vue-indexeddb","articles/jquery-database","articles/firestore-alternative","articles/firebase-realtime-database-alternative","articles/offline-database","articles/zero-latency-local-first"]},"contribute",{type:"category",label:"Contact",items:[{type:"link",label:"Consulting",href:"/consulting/"},{type:"link",label:"Discord",href:"/chat/",customProps:{target:"_blank"}},{type:"link",label:"LinkedIn",href:"https://www.linkedin.com/company/rxdb/"}]}]};var s=a(7587);function d(e){const t=(0,l.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,l.jsxs)("div",{className:"premium-block-inner",children:[(0,l.jsx)("h4",{style:{textDecoration:"none"},children:(0,s.Z2)(e.title)}),(0,l.jsx)("p",{children:e.text})]})});return e.href?(0,l.jsx)("a",{href:e.href,target:e.target,style:{textDecoration:"none"},children:t}):t}function n(){return console.log("sidebars:"),console.dir(c),(0,l.jsx)(l.Fragment,{children:c.tutorialSidebar.map((e=>{if(console.log("item: "+e.label),console.dir(e),"category"===e.type&&"articles"!==e.label.toLowerCase())return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("h2",{style:{width:"100%"},children:e.label}),(0,l.jsx)("div",{className:"premium-blocks",children:e.items.map((e=>"string"==typeof e?(0,l.jsx)(d,{title:p(e),href:"./"+e+".html"},e):(0,l.jsx)(d,{title:p(e.label),href:"link"===e.type?e.href:"./"+e.id+".html",target:"link"===e.type?"_blank":void 0},e.id)))},e.label)]})}))})}function p(e){const t=e.split("/");return(0,o.dG)(t)}const b={title:"RxDB Docs",slug:"overview.html",description:"RxDB Documentation Overview"},y="RxDB Documentation",m={},u=[];function g(e){const t={h1:"h1",header:"header",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t.header,{children:(0,l.jsx)(t.h1,{id:"rxdb-documentation",children:"RxDB Documentation"})}),"\n",(0,l.jsx)(n,{})]})}function x(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,l.jsx)(t,{...e,children:(0,l.jsx)(g,{...e})}):g(e)}},7587:(e,t,a)=>{a.d(t,{L$:()=>o,Z2:()=>i,zs:()=>l});var r="abcdefghijklmnopqrstuvwxyz";function l(e){void 0===e&&(e=10);for(var t="",a=0;a{a.d(t,{R:()=>o,x:()=>c});var r=a(6540);const l={},i=r.createContext(l);function o(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),r.createElement(i.Provider,{value:t},e.children)}},8653:(e,t,a)=>{function r(e){return e[e.length-1]}function l(e){return Array.isArray(e)?e.slice(0):[e]}function i(e){return Array.isArray(e)}function o(e,t){var a=0,r=-1;for(var l of e){if(!t(l,r+=1))break;a+=1}return a}function c(e,t){var a=t.length;if(0!==a){var r=e.length;e.length=r+t.length;for(var l=0;ll,Hb:()=>c,Sd:()=>o,dG:()=>r,jw:()=>s,k_:()=>i})}}]); \ No newline at end of file diff --git a/docs/assets/js/22dd74f7.e0562222.js b/docs/assets/js/22dd74f7.e0562222.js deleted file mode 100644 index a0ffd5b00b6..00000000000 --- a/docs/assets/js/22dd74f7.e0562222.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[1567],{5226:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Getting Started with RxDB","collapsed":false,"items":[{"type":"link","label":"\ud83d\ude80 Quickstart","href":"/quickstart.html","docId":"quickstart","unlisted":false},{"type":"link","label":"Installation","href":"/install.html","docId":"install","unlisted":false},{"type":"link","label":"Development Mode","href":"/dev-mode.html","docId":"dev-mode","unlisted":false},{"type":"link","label":"TypeScript Setup","href":"/tutorials/typescript.html","docId":"tutorials/typescript","unlisted":false}],"collapsible":true},{"type":"category","label":"Core Entities","collapsed":false,"items":[{"type":"link","label":"RxDatabase","href":"/rx-database.html","docId":"rx-database","unlisted":false},{"type":"link","label":"RxSchema","href":"/rx-schema.html","docId":"rx-schema","unlisted":false},{"type":"link","label":"RxCollection","href":"/rx-collection.html","docId":"rx-collection","unlisted":false},{"type":"link","label":"RxDocument","href":"/rx-document.html","docId":"rx-document","unlisted":false},{"type":"link","label":"RxQuery","href":"/rx-query.html","docId":"rx-query","unlisted":false}],"collapsible":true},{"type":"category","label":"\ud83d\udcbe Storages","items":[{"type":"link","label":"RxStorage Overview","href":"/rx-storage.html","docId":"rx-storage","unlisted":false},{"type":"link","label":"Dexie.js","href":"/rx-storage-dexie.html","docId":"rx-storage-dexie","unlisted":false},{"type":"link","label":"IndexedDB \ud83d\udc51","href":"/rx-storage-indexeddb.html","docId":"rx-storage-indexeddb","unlisted":false},{"type":"link","label":"OPFS \ud83d\udc51","href":"/rx-storage-opfs.html","docId":"rx-storage-opfs","unlisted":false},{"type":"link","label":"Memory","href":"/rx-storage-memory.html","docId":"rx-storage-memory","unlisted":false},{"type":"link","label":"SQLite \ud83d\udc51","href":"/rx-storage-sqlite.html","docId":"rx-storage-sqlite","unlisted":false},{"type":"link","label":"Filesystem Node \ud83d\udc51","href":"/rx-storage-filesystem-node.html","docId":"rx-storage-filesystem-node","unlisted":false},{"type":"link","label":"MongoDB","href":"/rx-storage-mongodb.html","docId":"rx-storage-mongodb","unlisted":false},{"type":"link","label":"DenoKV","href":"/rx-storage-denokv.html","docId":"rx-storage-denokv","unlisted":false},{"type":"link","label":"FoundationDB","href":"/rx-storage-foundationdb.html","docId":"rx-storage-foundationdb","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Storage Wrappers","items":[{"type":"link","label":"Schema Validation","href":"/schema-validation.html","docId":"schema-validation","unlisted":false},{"type":"link","label":"Encryption","href":"/encryption.html","docId":"encryption","unlisted":false},{"type":"link","label":"Key Compression","href":"/key-compression.html","docId":"key-compression","unlisted":false},{"type":"link","label":"Logger \ud83d\udc51","href":"/logger.html","docId":"logger","unlisted":false},{"type":"link","label":"Remote RxStorage","href":"/rx-storage-remote.html","docId":"rx-storage-remote","unlisted":false},{"type":"link","label":"Worker RxStorage \ud83d\udc51","href":"/rx-storage-worker.html","docId":"rx-storage-worker","unlisted":false},{"type":"link","label":"SharedWorker RxStorage \ud83d\udc51","href":"/rx-storage-shared-worker.html","docId":"rx-storage-shared-worker","unlisted":false},{"type":"link","label":"Memory Mapped RxStorage \ud83d\udc51","href":"/rx-storage-memory-mapped.html","docId":"rx-storage-memory-mapped","unlisted":false},{"type":"link","label":"Sharding \ud83d\udc51","href":"/rx-storage-sharding.html","docId":"rx-storage-sharding","unlisted":false},{"type":"link","label":"Localstorage Meta Optimizer \ud83d\udc51","href":"/rx-storage-localstorage-meta-optimizer.html","docId":"rx-storage-localstorage-meta-optimizer","unlisted":false},{"type":"link","label":"Electron","href":"/electron.html","docId":"electron","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"\ud83d\udd04 Replication","items":[{"type":"link","label":"\u2699\ufe0f Replication Protocol","href":"/replication.html","docId":"replication","unlisted":false},{"type":"link","label":"HTTP Replication","href":"/replication-http.html","docId":"replication-http","unlisted":false},{"type":"link","label":"RxServer Replication","href":"/replication-server.html","docId":"replication-server","unlisted":false},{"type":"link","label":"GraphQL Replication","href":"/replication-graphql.html","docId":"replication-graphql","unlisted":false},{"type":"link","label":"WebSocket Replication","href":"/replication-websocket.html","docId":"replication-websocket","unlisted":false},{"type":"link","label":"CouchDB Replication","href":"/replication-couchdb.html","docId":"replication-couchdb","unlisted":false},{"type":"link","label":"WebRTC P2P Replication","href":"/replication-webrtc.html","docId":"replication-webrtc","unlisted":false},{"type":"link","label":"Firestore Replication","href":"/replication-firestore.html","docId":"replication-firestore","unlisted":false},{"type":"link","label":"NATS Replication","href":"/replication-nats.html","docId":"replication-nats","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Server","items":[{"type":"link","label":"RxServer","href":"/rx-server.html","docId":"rx-server","unlisted":false},{"type":"link","label":"RxServer Scaling","href":"/rx-server-scaling.html","docId":"rx-server-scaling","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"How RxDB works","items":[{"type":"link","label":"Transactions Conflicts Revisions","href":"/transactions-conflicts-revisions.html","docId":"transactions-conflicts-revisions","unlisted":false},{"type":"link","label":"Query Cache","href":"/query-cache.html","docId":"query-cache","unlisted":false},{"type":"link","label":"Creating Plugins","href":"/plugins.html","docId":"plugins","unlisted":false},{"type":"link","label":"Errors","href":"/errors.html","docId":"errors","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Advanced Features","items":[{"type":"category","label":"Migration","items":[{"type":"link","label":"Schema Migration","href":"/migration-schema.html","docId":"migration-schema","unlisted":false},{"type":"link","label":"Storage Migration","href":"/migration-storage.html","docId":"migration-storage","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Attachments","href":"/rx-attachment.html","docId":"rx-attachment","unlisted":false},{"type":"link","label":"RxPipelines","href":"/rx-pipeline.html","docId":"rx-pipeline","unlisted":false},{"type":"link","label":"Custom Reactivity","href":"/reactivity.html","docId":"reactivity","unlisted":false},{"type":"link","label":"RxState","href":"/rx-state.html","docId":"rx-state","unlisted":false},{"type":"link","label":"Local Documents","href":"/rx-local-document.html","docId":"rx-local-document","unlisted":false},{"type":"link","label":"Cleanup","href":"/cleanup.html","docId":"cleanup","unlisted":false},{"type":"link","label":"Backup","href":"/backup.html","docId":"backup","unlisted":false},{"type":"link","label":"Leader Election","href":"/leader-election.html","docId":"leader-election","unlisted":false},{"type":"link","label":"Middleware","href":"/middleware.html","docId":"middleware","unlisted":false},{"type":"link","label":"CRDT","href":"/crdt.html","docId":"crdt","unlisted":false},{"type":"link","label":"Population","href":"/population.html","docId":"population","unlisted":false},{"type":"link","label":"ORM","href":"/orm.html","docId":"orm","unlisted":false},{"type":"link","label":"Fulltext Search \ud83d\udc51","href":"/fulltext-search.html","docId":"fulltext-search","unlisted":false},{"type":"link","label":"Vector Database","href":"/articles/javascript-vector-database.html","docId":"articles/javascript-vector-database","unlisted":false},{"type":"link","label":"Query Optimizer \ud83d\udc51","href":"/query-optimizer.html","docId":"query-optimizer","unlisted":false},{"type":"link","label":"Third Party Plugins","href":"/third-party-plugins.html","docId":"third-party-plugins","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Performance","items":[{"type":"link","label":"RxStorage Performance","href":"/rx-storage-performance.html","docId":"rx-storage-performance","unlisted":false},{"type":"link","label":"NoSQL Performance Tips","href":"/nosql-performance-tips.html","docId":"nosql-performance-tips","unlisted":false},{"type":"link","label":"Slow IndexedDB","href":"/slow-indexeddb.html","docId":"slow-indexeddb","unlisted":false},{"type":"link","label":"LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite","href":"/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html","docId":"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Releases","items":[{"type":"link","label":"16.0.0","href":"/releases/16.0.0.html","docId":"releases/16.0.0","unlisted":false},{"type":"link","label":"15.0.0","href":"/releases/15.0.0.html","docId":"releases/15.0.0","unlisted":false},{"type":"link","label":"14.0.0","href":"/releases/14.0.0.html","docId":"releases/14.0.0","unlisted":false},{"type":"link","label":"13.0.0","href":"/releases/13.0.0.html","docId":"releases/13.0.0","unlisted":false},{"type":"link","label":"12.0.0","href":"/releases/12.0.0.html","docId":"releases/12.0.0","unlisted":false},{"type":"link","label":"11.0.0","href":"/releases/11.0.0.html","docId":"releases/11.0.0","unlisted":false},{"type":"link","label":"10.0.0","href":"/releases/10.0.0.html","docId":"releases/10.0.0","unlisted":false},{"type":"link","label":"9.0.0","href":"/releases/9.0.0.html","docId":"releases/9.0.0","unlisted":false},{"type":"link","label":"8.0.0","href":"/releases/8.0.0.html","docId":"releases/8.0.0","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Articles","items":[{"type":"link","label":"Local First / Offline First","href":"/offline-first.html","docId":"offline-first","unlisted":false},{"type":"link","label":"Downsides of Local First / Offline First","href":"/downsides-of-offline-first.html","docId":"downsides-of-offline-first","unlisted":false},{"type":"link","label":"Why NoSQL Powers Modern UI Apps","href":"/why-nosql.html","docId":"why-nosql","unlisted":false},{"type":"link","label":"RxDB - The Real-Time Database for Node.js","href":"/nodejs-database.html","docId":"nodejs-database","unlisted":false},{"type":"link","label":"Alternatives for realtime local-first JavaScript applications and local databases","href":"/alternatives.html","docId":"alternatives","unlisted":false},{"type":"link","label":"React Native Database - Sync & Store Like a Pro","href":"/react-native-database.html","docId":"react-native-database","unlisted":false},{"type":"link","label":"RxDB as a Database in an Angular Application","href":"/articles/angular-database.html","docId":"articles/angular-database","unlisted":false},{"type":"link","label":"Benefits of RxDB & Browser Databases","href":"/articles/browser-database.html","docId":"articles/browser-database","unlisted":false},{"type":"link","label":"Browser Storage - RxDB as a Database for Browsers","href":"/articles/browser-storage.html","docId":"articles/browser-storage","unlisted":false},{"type":"link","label":"Empower Web Apps with Reactive RxDB Data-base","href":"/articles/data-base.html","docId":"articles/data-base","unlisted":false},{"type":"link","label":"Embedded Database, Real-time Speed - RxDB","href":"/articles/embedded-database.html","docId":"articles/embedded-database","unlisted":false},{"type":"link","label":"Supercharge Flutter Apps with the RxDB Database","href":"/articles/flutter-database.html","docId":"articles/flutter-database","unlisted":false},{"type":"link","label":"RxDB - The Ultimate JS Frontend Database","href":"/articles/frontend-database.html","docId":"articles/frontend-database","unlisted":false},{"type":"link","label":"RxDB In-Memory NoSQL - Supercharge Real-Time Apps","href":"/articles/in-memory-nosql-database.html","docId":"articles/in-memory-nosql-database","unlisted":false},{"type":"link","label":"RxDB - The Perfect Ionic Database","href":"/articles/ionic-database.html","docId":"articles/ionic-database","unlisted":false},{"type":"link","label":"RxDB - Local Ionic Storage with Encryption, Compression & Sync","href":"/articles/ionic-storage.html","docId":"articles/ionic-storage","unlisted":false},{"type":"link","label":"RxDB - The JSON Database Built for JavaScript","href":"/articles/json-database.html","docId":"articles/json-database","unlisted":false},{"type":"link","label":"WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport","href":"/articles/websockets-sse-polling-webrtc-webtransport.html","docId":"articles/websockets-sse-polling-webrtc-webtransport","unlisted":false},{"type":"link","label":"Using localStorage in Modern Applications - A Comprehensive Guide","href":"/articles/localstorage.html","docId":"articles/localstorage","unlisted":false},{"type":"link","label":"Real-Time & Offline - RxDB for Mobile Apps","href":"/articles/mobile-database.html","docId":"articles/mobile-database","unlisted":false},{"type":"link","label":"RxDB as a Database for Progressive Web Apps (PWA)","href":"/articles/progressive-web-app-database.html","docId":"articles/progressive-web-app-database","unlisted":false},{"type":"link","label":"RxDB as a Database for React Applications","href":"/articles/react-database.html","docId":"articles/react-database","unlisted":false},{"type":"link","label":"What Really Is a Realtime Database?","href":"/articles/realtime-database.html","docId":"articles/realtime-database","unlisted":false},{"type":"link","label":"Build Smarter Offline-First Angular Apps - How RxDB Beats IndexedDB Alone","href":"/articles/angular-indexeddb.html","docId":"articles/angular-indexeddb","unlisted":false},{"type":"link","label":"IndexedDB Database in React Apps - The Power of RxDB","href":"/articles/react-indexeddb.html","docId":"articles/react-indexeddb","unlisted":false},{"type":"link","label":"Capacitor Database Guide - SQLite, RxDB & More","href":"/capacitor-database.html","docId":"capacitor-database","unlisted":false},{"type":"link","label":"Electron Database - Storage adapters for SQLite, Filesystem and In-Memory","href":"/electron-database.html","docId":"electron-database","unlisted":false},{"type":"link","label":"Building an Optimistic UI with RxDB","href":"/articles/optimistic-ui.html","docId":"articles/optimistic-ui","unlisted":false},{"type":"link","label":"What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications","href":"/articles/local-database.html","docId":"articles/local-database","unlisted":false},{"type":"link","label":"React Native Encryption and Encrypted Database/Storage","href":"/articles/react-native-encryption.html","docId":"articles/react-native-encryption","unlisted":false},{"type":"link","label":"RxDB as a Database in a Vue.js Application","href":"/articles/vue-database.html","docId":"articles/vue-database","unlisted":false},{"type":"link","label":"IndexedDB Database in Vue Apps - The Power of RxDB","href":"/articles/vue-indexeddb.html","docId":"articles/vue-indexeddb","unlisted":false},{"type":"link","label":"RxDB as a Database in a jQuery Application","href":"/articles/jquery-database.html","docId":"articles/jquery-database","unlisted":false},{"type":"link","label":"RxDB - Firestore Alternative to Sync with Your Own Backend","href":"/articles/firestore-alternative.html","docId":"articles/firestore-alternative","unlisted":false},{"type":"link","label":"RxDB - Firebase Realtime Database Alternative to Sync With Your Own Backend","href":"/articles/firebase-realtime-database-alternative.html","docId":"articles/firebase-realtime-database-alternative","unlisted":false},{"type":"link","label":"RxDB \u2013 The Ultimate Offline Database with Sync and Encryption","href":"/articles/offline-database.html","docId":"articles/offline-database","unlisted":false},{"type":"link","label":"Zero Latency Local First Apps with RxDB \u2013 Sync, Encryption and Compression","href":"/articles/zero-latency-local-first.html","docId":"articles/zero-latency-local-first","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Contribute & Innovate with RxDB","href":"/contribution.html","docId":"contribute","unlisted":false},{"type":"category","label":"Contact","items":[{"type":"link","label":"Consulting","href":"/consulting/"},{"type":"link","label":"Discord","href":"/chat/","customProps":{"target":"_blank"}},{"type":"link","label":"LinkedIn","href":"https://www.linkedin.com/company/rxdb/"}],"collapsed":true,"collapsible":true}]},"docs":{"adapters":{"id":"adapters","title":"PouchDB Adapters","description":"When you use PouchDB RxStorage, there are many adapters that define where the data has to be stored."},"alternatives":{"id":"alternatives","title":"Alternatives for realtime local-first JavaScript applications and local databases","description":"Explore real-time, local-first JS alternatives to RxDB. Compare Firebase, Meteor, AWS, CouchDB, and more for robust, seamless web/mobile app development.","sidebar":"tutorialSidebar"},"articles/angular-database":{"id":"articles/angular-database","title":"RxDB as a Database in an Angular Application","description":"Level up your Angular projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/angular-indexeddb":{"id":"articles/angular-indexeddb","title":"Build Smarter Offline-First Angular Apps - How RxDB Beats IndexedDB Alone","description":"Discover how to harness IndexedDB in Angular with RxDB for robust offline apps. Learn reactive queries, advanced features, and more.","sidebar":"tutorialSidebar"},"articles/browser-database":{"id":"articles/browser-database","title":"Benefits of RxDB & Browser Databases","description":"Find out why RxDB is the go-to solution for browser databases. See how it boosts performance, simplifies replication, and powers real-time UIs.","sidebar":"tutorialSidebar"},"articles/browser-storage":{"id":"articles/browser-storage","title":"Browser Storage - RxDB as a Database for Browsers","description":"Explore RxDB for browser storage its advantages, limitations, and why it outperforms SQL databases in web applications for enhanced efficiency","sidebar":"tutorialSidebar"},"articles/data-base":{"id":"articles/data-base","title":"Empower Web Apps with Reactive RxDB Data-base","description":"Explore RxDB\'s reactive data-base solution for web and mobile. Enable offline-first experiences, real-time syncing, and secure data handling with ease.","sidebar":"tutorialSidebar"},"articles/embedded-database":{"id":"articles/embedded-database","title":"Embedded Database, Real-time Speed - RxDB","description":"Unleash the power of embedded databases with RxDB. Explore real-time replication, offline access, and reactive queries for modern JavaScript apps.","sidebar":"tutorialSidebar"},"articles/firebase-realtime-database-alternative":{"id":"articles/firebase-realtime-database-alternative","title":"RxDB - Firebase Realtime Database Alternative to Sync With Your Own Backend","description":"Looking for a Firebase Realtime Database alternative? RxDB offers a fully offline, vendor-agnostic NoSQL solution with advanced conflict resolution and multi-platform support.","sidebar":"tutorialSidebar"},"articles/firestore-alternative":{"id":"articles/firestore-alternative","title":"RxDB - Firestore Alternative to Sync with Your Own Backend","description":"Looking for a Firestore alternative? RxDB is a local-first, NoSQL database that syncs seamlessly with any backend, offers rich offline capabilities, advanced conflict resolution, and reduces vendor lock-in.","sidebar":"tutorialSidebar"},"articles/flutter-database":{"id":"articles/flutter-database","title":"Supercharge Flutter Apps with the RxDB Database","description":"Harness RxDB\'s reactive database to bring real-time, offline-first data storage and syncing to your next Flutter application.","sidebar":"tutorialSidebar"},"articles/frontend-database":{"id":"articles/frontend-database","title":"RxDB - The Ultimate JS Frontend Database","description":"Discover how RxDB, a powerful JavaScript frontend database, boosts offline access, caching, and real-time updates to supercharge your web apps.","sidebar":"tutorialSidebar"},"articles/ideas":{"id":"articles/ideas","title":"ideas for articles","description":"- storing and searching through 1mio emails in a browser database"},"articles/in-memory-nosql-database":{"id":"articles/in-memory-nosql-database","title":"RxDB In-Memory NoSQL - Supercharge Real-Time Apps","description":"Discover how RxDB\'s in-memory NoSQL engine delivers blazing speed for real-time apps, ensuring responsive experiences and seamless data sync.","sidebar":"tutorialSidebar"},"articles/ionic-database":{"id":"articles/ionic-database","title":"RxDB - The Perfect Ionic Database","description":"Supercharge your Ionic hybrid apps with RxDB\'s offline-first database. Experience real-time sync, top performance, and easy replication.","sidebar":"tutorialSidebar"},"articles/ionic-storage":{"id":"articles/ionic-storage","title":"RxDB - Local Ionic Storage with Encryption, Compression & Sync","description":"The best Ionic storage solution? RxDB empowers your hybrid apps with offline-first capabilities, secure encryption, data compression, and seamless data syncing to any backend.","sidebar":"tutorialSidebar"},"articles/javascript-vector-database":{"id":"articles/javascript-vector-database","title":"JavaScript Vector Database that runs locally and works offline","description":"Create a blazing-fast vector database in JavaScript. Leverage RxDB and transformers.js for instant, offline semantic search - no servers required!","sidebar":"tutorialSidebar"},"articles/jquery-database":{"id":"articles/jquery-database","title":"RxDB as a Database in a jQuery Application","description":"Level up your jQuery-based projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/json-database":{"id":"articles/json-database","title":"RxDB - The JSON Database Built for JavaScript","description":"Experience a powerful JSON database with RxDB, built for JavaScript. Store, sync, and compress your data seamlessly across web and mobile apps.","sidebar":"tutorialSidebar"},"articles/local-database":{"id":"articles/local-database","title":"What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications","description":"An in-depth exploration of local databases and why RxDB excels as a local-first solution for JavaScript applications.","sidebar":"tutorialSidebar"},"articles/localstorage":{"id":"articles/localstorage","title":"Using localStorage in Modern Applications - A Comprehensive Guide","description":"This guide explores localStorage in JavaScript web apps, detailing its usage, limitations, and alternatives like IndexedDB and AsyncStorage.","sidebar":"tutorialSidebar"},"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm":{"id":"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm","title":"LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite","description":"Compare LocalStorage, IndexedDB, Cookies, OPFS, and WASM-SQLite for web storage, performance, limits, and best practices for modern web apps.","sidebar":"tutorialSidebar"},"articles/mobile-database":{"id":"articles/mobile-database","title":"Real-Time & Offline - RxDB for Mobile Apps","description":"Explore RxDB as your reliable mobile database. Enjoy offline-first capabilities, real-time sync, and seamless integration for hybrid app development.","sidebar":"tutorialSidebar"},"articles/offline-database":{"id":"articles/offline-database","title":"RxDB \u2013 The Ultimate Offline Database with Sync and Encryption","description":"Discover how RxDB serves as a powerful offline database, offering real-time synchronization, secure encryption, and an offline-first approach for modern web and mobile apps.","sidebar":"tutorialSidebar"},"articles/optimistic-ui":{"id":"articles/optimistic-ui","title":"Building an Optimistic UI with RxDB","description":"Learn how to build an Optimistic UI with RxDB for instant and reliable UI updates on user interactions","sidebar":"tutorialSidebar"},"articles/progressive-web-app-database":{"id":"articles/progressive-web-app-database","title":"RxDB as a Database for Progressive Web Apps (PWA)","description":"Discover how RxDB supercharges Progressive Web Apps with real-time sync, offline-first capabilities, and lightning-fast data handling.","sidebar":"tutorialSidebar"},"articles/react-database":{"id":"articles/react-database","title":"RxDB as a Database for React Applications","description":"earn how the RxDB database supercharges React apps with offline access, real-time updates, and smooth data flow. Boost performance and engagement.","sidebar":"tutorialSidebar"},"articles/react-indexeddb":{"id":"articles/react-indexeddb","title":"IndexedDB Database in React Apps - The Power of RxDB","description":"Discover how RxDB simplifies IndexedDB in React, offering reactive queries, offline-first capability, encryption, compression, and effortless integration.","sidebar":"tutorialSidebar"},"articles/react-native-encryption":{"id":"articles/react-native-encryption","title":"React Native Encryption and Encrypted Database/Storage","description":"Secure your React Native app with RxDB encryption. Learn why it matters, how to implement encrypted databases, and best practices to protect user data.","sidebar":"tutorialSidebar"},"articles/realtime-database":{"id":"articles/realtime-database","title":"What Really Is a Realtime Database?","description":"Discover how RxDB merges realtime replication and dynamic updates to deliver seamless data sync across browsers, devices, and servers - instantly.","sidebar":"tutorialSidebar"},"articles/vue-database":{"id":"articles/vue-database","title":"RxDB as a Database in a Vue.js Application","description":"Level up your Vue projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/vue-indexeddb":{"id":"articles/vue-indexeddb","title":"IndexedDB Database in Vue Apps - The Power of RxDB","description":"Learn how RxDB simplifies IndexedDB in Vue, offering reactive queries, offline-first capabilities, encryption, compression, and effortless integration.","sidebar":"tutorialSidebar"},"articles/websockets-sse-polling-webrtc-webtransport":{"id":"articles/websockets-sse-polling-webrtc-webtransport","title":"WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport","description":"Learn the unique benefits and pitfalls of each real-time tech. Make informed decisions on WebSockets, SSE, Polling, WebRTC, and WebTransport.","sidebar":"tutorialSidebar"},"articles/zero-latency-local-first":{"id":"articles/zero-latency-local-first","title":"Zero Latency Local First Apps with RxDB \u2013 Sync, Encryption and Compression","description":"Build blazing-fast, zero-latency local first apps with RxDB. Gain instant UI responses, robust offline capabilities, end-to-end encryption, and data compression for streamlined performance.","sidebar":"tutorialSidebar"},"backup":{"id":"backup","title":"Backup","description":"Easily back up your RxDB database to JSON files and attachments on the filesystem with the Backup Plugin - ensuring reliable Node.js data protection.","sidebar":"tutorialSidebar"},"capacitor-database":{"id":"capacitor-database","title":"Capacitor Database Guide - SQLite, RxDB & More","description":"Explore Capacitor\'s top data storage solutions - from key-value to real-time databases. Compare SQLite, RxDB, and more in this in-depth guide.","sidebar":"tutorialSidebar"},"cleanup":{"id":"cleanup","title":"Cleanup","description":"Optimize storage and speed up queries with RxDB\'s Cleanup Plugin, automatically removing old deleted docs while preserving replication states.","sidebar":"tutorialSidebar"},"contribute":{"id":"contribute","title":"Contribute & Innovate with RxDB","description":"Got a fix or fresh idea? Learn how to contribute to RxDB, run tests, and shape the future of this cutting-edge NoSQL database for JavaScript.","sidebar":"tutorialSidebar"},"crdt":{"id":"crdt","title":"CRDT - Conflict-free replicated data type Database","description":"Learn how RxDB\'s CRDT Plugin resolves document conflicts automatically in distributed systems, ensuring seamless merges and consistent data.","sidebar":"tutorialSidebar"},"data-migration":{"id":"data-migration","title":"Data Migration","description":"This documentation page has been moved to here"},"dev-mode":{"id":"dev-mode","title":"Development Mode","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production.","sidebar":"tutorialSidebar"},"downsides-of-offline-first":{"id":"downsides-of-offline-first","title":"Downsides of Local First / Offline First","description":"Discover the hidden pitfalls of local-first apps. Learn about storage limits, conflicts, and real-time illusions before building your offline solution.","sidebar":"tutorialSidebar"},"electron":{"id":"electron","title":"Seamless Electron Storage with RxDB","description":"Use the RxDB Electron Plugin to share data between main and renderer processes. Enjoy quick queries, real-time sync, and robust offline support.","sidebar":"tutorialSidebar"},"electron-database":{"id":"electron-database","title":"Electron Database - Storage adapters for SQLite, Filesystem and In-Memory","description":"Harness the database power of SQLite, Filesystem, and in-memory storage in Electron with RxDB. Build fast, offline-first apps that sync in real time.","sidebar":"tutorialSidebar"},"encryption":{"id":"encryption","title":"Encryption","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage.","sidebar":"tutorialSidebar"},"errors":{"id":"errors","title":"Error Messages","description":"Learn how RxDB throws RxErrors with codes and parameters. Keep builds lean, yet unveil full messages in development via the DevMode plugin.","sidebar":"tutorialSidebar"},"fulltext-search":{"id":"fulltext-search","title":"Fulltext Search \ud83d\udc51","description":"Master local fulltext search with RxDB\'s FlexSearch plugin. Enjoy real-time indexing, efficient queries, and offline-first support made easy.","sidebar":"tutorialSidebar"},"install":{"id":"install","title":"Installation","description":"Learn how to install RxDB via npm, configure polyfills, and fix global variable errors in Angular or Webpack for a seamless setup.","sidebar":"tutorialSidebar"},"key-compression":{"id":"key-compression","title":"Key Compression","description":"With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.","sidebar":"tutorialSidebar"},"leader-election":{"id":"leader-election","title":"Leader Election","description":"RxDB comes with a leader-election which elects a leading instance between different instances in the same javascript runtime.","sidebar":"tutorialSidebar"},"logger":{"id":"logger","title":"RxDB Logger Plugin - Track & Optimize","description":"Take control of your RxDatabase logs. Monitor every write, query, or attachment retrieval to swiftly diagnose and fix performance bottlenecks.","sidebar":"tutorialSidebar"},"middleware":{"id":"middleware","title":"Streamlined RxDB Middleware","description":"Enhance your RxDB workflow with pre and post hooks. Quickly add custom validations, triggers, and events to streamline your asynchronous operations.","sidebar":"tutorialSidebar"},"migration-schema":{"id":"migration-schema","title":"Seamless Schema Data Migration with RxDB","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly.","sidebar":"tutorialSidebar"},"migration-storage":{"id":"migration-storage","title":"Migration Storage","description":"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:","sidebar":"tutorialSidebar"},"nodejs-database":{"id":"nodejs-database","title":"RxDB - The Real-Time Database for Node.js","description":"Discover how RxDB brings flexible, reactive NoSQL to Node.js. Scale effortlessly, persist data, and power your server-side apps with ease.","sidebar":"tutorialSidebar"},"nosql-performance-tips":{"id":"nosql-performance-tips","title":"RxDB NoSQL Performance Tips","description":"Skyrocket your NoSQL speed with RxDB tips. Learn about bulk writes, optimized queries, and lean plugin usage for peak performance.","sidebar":"tutorialSidebar"},"offline-first":{"id":"offline-first","title":"Local First / Offline First","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency.","sidebar":"tutorialSidebar"},"orm":{"id":"orm","title":"ORM","description":"Like mongoose, RxDB has ORM-capabilities which can be used to add specific behavior to documents and collections.","sidebar":"tutorialSidebar"},"plugins":{"id":"plugins","title":"Creating Plugins","description":"Creating your own plugin is very simple. A plugin is basically a javascript-object which overwrites or extends RxDB\'s internal classes, prototypes, and hooks.","sidebar":"tutorialSidebar"},"population":{"id":"population","title":"Populate and Link Docs in RxDB","description":"Learn how to reference and link documents across collections in RxDB. Discover easy population without joins and handle complex relationships.","sidebar":"tutorialSidebar"},"query-cache":{"id":"query-cache","title":"Efficient RxDB Queries via Query Cache","description":"Learn how RxDB\'s Query Cache boosts performance by reusing queries. Discover its default replacement policy and how to define your own.","sidebar":"tutorialSidebar"},"query-optimizer":{"id":"query-optimizer","title":"Optimize Client-Side Queries with RxDB","description":"Harness real-world data to fine-tune queries. The build-time RxDB Optimizer finds the perfect index, boosting query speed in any environment.","sidebar":"tutorialSidebar"},"quickstart":{"id":"quickstart","title":"\ud83d\ude80 Quickstart","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing.","sidebar":"tutorialSidebar"},"react-native-database":{"id":"react-native-database","title":"React Native Database - Sync & Store Like a Pro","description":"Discover top React Native local database solutions - AsyncStorage, SQLite, RxDB, and more. Build offline-ready apps for iOS, Android, and Windows with easy sync.","sidebar":"tutorialSidebar"},"reactivity":{"id":"reactivity","title":"Signals & Custom Reactivity with RxDB","description":"Level up reactivity with Angular signals, Vue refs, or Preact signals in RxDB. Learn how to integrate custom reactivity to power your dynamic UI.","sidebar":"tutorialSidebar"},"releases/10.0.0":{"id":"releases/10.0.0","title":"RxDB 10.0.0 - Built for the Future","description":"Experience faster, future-proof data handling in RxDB 10.0. Explore new storage interfaces, composite keys, and major performance upgrades.","sidebar":"tutorialSidebar"},"releases/11.0.0":{"id":"releases/11.0.0","title":"RxDB 11 - WebWorker Support & More","description":"RxDB 11.0 brings Worker-based storage for multi-core performance gains. Explore the major changes and migrate seamlessly to harness new speeds.","sidebar":"tutorialSidebar"},"releases/12.0.0":{"id":"releases/12.0.0","title":"RxDB 12.0.0 - Clean, Lean & Mean","description":"Upgrade to RxDB 12.0.0 for blazing-fast queries, streamlined replication, and better index usage. Explore new features and power up your app.","sidebar":"tutorialSidebar"},"releases/13.0.0":{"id":"releases/13.0.0","title":"RxDB 13.0.0 - A New Era of Replication","description":"Discover RxDB 13.0\'s brand-new replication protocol, faster performance, and real-time collaboration for a seamless offline-first experience.","sidebar":"tutorialSidebar"},"releases/14.0.0":{"id":"releases/14.0.0","title":"RxDB 14.0 - Major Changes & New Features","description":"Discover RxDB 14.0, a major release packed with API changes, improved performance, and streamlined storage, ensuring faster data operations than ever.","sidebar":"tutorialSidebar"},"releases/15.0.0":{"id":"releases/15.0.0","title":"RxDB 15.0.0 - Major Migration Overhaul","description":"Discover RxDB 15.0.0, featuring new migration strategies, replication improvements, and lightning-fast performance to supercharge your app.","sidebar":"tutorialSidebar"},"releases/16.0.0":{"id":"releases/16.0.0","title":"RxDB 16.0.0 - Efficiency Redefined","description":"Meet RxDB 16.0.0 - major refactorings, improved performance, and easy migrations. Experience a better, faster, and more stable database solution today.","sidebar":"tutorialSidebar"},"releases/8.0.0":{"id":"releases/8.0.0","title":"Meet RxDB 8.0.0 - New Defaults & Performance","description":"Discover how RxDB 8.0.0 boosts performance, simplifies schema handling, and streamlines reactive data updates for modern apps.","sidebar":"tutorialSidebar"},"releases/9.0.0":{"id":"releases/9.0.0","title":"RxDB 9.0.0 - Faster & Simpler","description":"Discover RxDB 9.0.0\'s streamlined plugins, top-level schema definitions, and improved dev-mode. Experience a simpler, faster real-time database.","sidebar":"tutorialSidebar"},"replication":{"id":"replication","title":"\u2699\ufe0f Replication Protocol","description":"Replicate data in real-time with RxDB\'s offline-first protocol. Enjoy efficient syncing, conflict resolution, and advanced multi-tab support.","sidebar":"tutorialSidebar"},"replication-couchdb":{"id":"replication-couchdb","title":"RxDB\'s CouchDB Replication Plugin","description":"Replicate your RxDB collections with CouchDB the fast way. Enjoy faster sync, easier conflict handling, and flexible storage using this modern plugin.","sidebar":"tutorialSidebar"},"replication-firestore":{"id":"replication-firestore","title":"Smooth Firestore Sync for Offline Apps","description":"Leverage RxDB to enable real-time, offline-first replication with Firestore. Cut cloud costs, resolve conflicts, and speed up your app.","sidebar":"tutorialSidebar"},"replication-graphql":{"id":"replication-graphql","title":"GraphQL Replication","description":"The GraphQL replication provides handlers for GraphQL to run replication with GraphQL as the transportation layer.","sidebar":"tutorialSidebar"},"replication-http":{"id":"replication-http","title":"HTTP Replication","description":"Learn how to establish HTTP replication between RxDB clients and a Node.js Express server for data synchronization.","sidebar":"tutorialSidebar"},"replication-nats":{"id":"replication-nats","title":"RxDB & NATS - Realtime Sync","description":"Seamlessly sync your RxDB data with NATS for real-time, two-way replication. Handle conflicts, errors, and retries with ease.","sidebar":"tutorialSidebar"},"replication-p2p":{"id":"replication-p2p","title":"Seamless P2P Data Sync","description":"Discover how replication-webrtc ensures secure P2P data sync and real-time collaboration with RxDB. Explore the future of offline-first apps!"},"replication-server":{"id":"replication-server","title":"RxDB Server Replication","description":"The Server Replication Plugin connects to the replication endpoint of an RxDB Server Replication Endpoint and replicates data between the client and the server.","sidebar":"tutorialSidebar"},"replication-webrtc":{"id":"replication-webrtc","title":"WebRTC P2P Replication with RxDB - Sync Browsers and Devices","description":"Learn to set up peer-to-peer WebRTC replication with RxDB. Bypass central servers and enjoy secure, low-latency data sync across all clients.","sidebar":"tutorialSidebar"},"replication-websocket":{"id":"replication-websocket","title":"Websocket Replication","description":"With the websocket replication plugin, you can spawn a websocket server from a RxDB database in Node.js and replicate with it.","sidebar":"tutorialSidebar"},"rx-attachment":{"id":"rx-attachment","title":"Attachments","description":"Attachments are binary data files that can be attachment to an RxDocument, like a file that is attached to an email.","sidebar":"tutorialSidebar"},"rx-collection":{"id":"rx-collection","title":"Master Data - Create and Manage RxCollections","description":"Discover how to create, manage, and migrate documents in RxCollections. Harness real-time data flows, secure encryption, and powerful performance in RxDB.","sidebar":"tutorialSidebar"},"rx-database":{"id":"rx-database","title":"RxDatabase - The Core of Your Realtime Data","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today.","sidebar":"tutorialSidebar"},"rx-document":{"id":"rx-document","title":"RxDocument","description":"Master RxDB\'s RxDocument - Insert, find, update, remove, and more for streamlined data handling in modern apps.","sidebar":"tutorialSidebar"},"rx-local-document":{"id":"rx-local-document","title":"Master Local Documents in RxDB","description":"Effortlessly store custom metadata and app settings in RxDB. Learn how Local Documents keep data flexible, secure, and easy to manage.","sidebar":"tutorialSidebar"},"rx-pipeline":{"id":"rx-pipeline","title":"RxPipeline - Automate Data Flows in RxDB","description":"Discover how RxPipeline automates your data workflows. Seamlessly process writes, manage leader election, and ensure crash-safe operations in RxDB.","sidebar":"tutorialSidebar"},"rx-query":{"id":"rx-query","title":"RxQuery","description":"Master RxQuery in RxDB - find, update, remove documents using Mango syntax, chained queries, real-time observations, indexing, and more.","sidebar":"tutorialSidebar"},"rx-schema":{"id":"rx-schema","title":"Design Perfect Schemas in RxDB","description":"Learn how to define, secure, and validate your data in RxDB. Master primary keys, indexes, encryption, and more with the RxSchema approach.","sidebar":"tutorialSidebar"},"rx-server":{"id":"rx-server","title":"RxDB Server - Deploy Your Data","description":"Launch a secure, high-performance server on top of your RxDB database. Enable REST, replication endpoints, and seamless data syncing with RxServer.","sidebar":"tutorialSidebar"},"rx-server-scaling":{"id":"rx-server-scaling","title":"RxServer Scaling - Vertical or Horizontal","description":"Discover vertical and horizontal techniques to boost RxServer. Learn multiple processes, worker threads, and replication for limitless performance.","sidebar":"tutorialSidebar"},"rx-state":{"id":"rx-state","title":"Effortless Reactive State with RxDB\'s RxState","description":"Get real-time, persistent state without the hassle. RxState integrates easily with signals and hooks, ensuring smooth updates across tabs and devices.","sidebar":"tutorialSidebar"},"rx-storage":{"id":"rx-storage","title":"\u2699\ufe0f RxStorage Layer - Choose the Perfect RxDB Storage for Every Use Case","description":"Discover how RxDB\'s modular RxStorage lets you swap engines and unlock top performance, no matter the environment or use case.","sidebar":"tutorialSidebar"},"rx-storage-denokv":{"id":"rx-storage-denokv","title":"DenoKV RxStorage","description":"With the DenoKV RxStorage layer for RxDB, you can run a fully featured NoSQL database on top of the DenoKV API.","sidebar":"tutorialSidebar"},"rx-storage-dexie":{"id":"rx-storage-dexie","title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes.","sidebar":"tutorialSidebar"},"rx-storage-filesystem-node":{"id":"rx-storage-filesystem-node","title":"Blazing-Fast Node Filesystem Storage","description":"Get up and running quickly with RxDB\'s Filesystem Node RxStorage. Store data in JSON, embrace multi-instance support, and enjoy a simpler database.","sidebar":"tutorialSidebar"},"rx-storage-foundationdb":{"id":"rx-storage-foundationdb","title":"RxDB on FoundationDB - Performance at Scale","description":"Combine FoundationDB\'s reliability with RxDB\'s indexing and schema validation. Build scalable apps with faster queries and real-time data.","sidebar":"tutorialSidebar"},"rx-storage-indexeddb":{"id":"rx-storage-indexeddb","title":"Instant Performance with IndexedDB RxStorage","description":"Choose IndexedDB RxStorage for unmatched speed and minimal build size. Perfect for fast-performing apps that demand reliable, lightweight data solutions.","sidebar":"tutorialSidebar"},"rx-storage-localstorage-meta-optimizer":{"id":"rx-storage-localstorage-meta-optimizer","title":"Fastest RxDB Starts - Localstorage Meta Optimizer","description":"Wrap any RxStorage with localStorage metadata to slash initial load by up to 200ms. Unlock speed with this must-have RxDB Premium plugin.","sidebar":"tutorialSidebar"},"rx-storage-lokijs":{"id":"rx-storage-lokijs","title":"Empower RxDB with the LokiJS RxStorage","description":"Discover the lightning-fast LokiJS RxStorage for RxDB. Explore in-memory speed, multi-tab support, and pros & cons of this unique storage solution."},"rx-storage-memory":{"id":"rx-storage-memory","title":"Lightning-Fast Memory Storage for RxDB","description":"Use Memory RxStorage for a high-performance, JavaScript in-memory database. Built for speed, making it perfect for unit tests and rapid prototyping.","sidebar":"tutorialSidebar"},"rx-storage-memory-mapped":{"id":"rx-storage-memory-mapped","title":"Blazing-Fast Memory Mapped RxStorage","description":"Boost your app\'s performance with Memory Mapped RxStorage. Query and write in-memory while seamlessly persisting data to your chosen storage.","sidebar":"tutorialSidebar"},"rx-storage-memory-synced":{"id":"rx-storage-memory-synced","title":"Instant Performance with Memory Synced RxStorage","description":"Accelerate RxDB with in-memory storage replicated to disk. Enjoy instant queries, faster loads, and unstoppable performance for your web apps."},"rx-storage-mongodb":{"id":"rx-storage-mongodb","title":"Unlock MongoDB Power with RxDB","description":"Combine RxDB\'s real-time sync with MongoDB\'s scalability. Harness the MongoDB RxStorage to seamlessly expand your database capabilities.","sidebar":"tutorialSidebar"},"rx-storage-opfs":{"id":"rx-storage-opfs","title":"Supercharged OPFS Database with RxDB","description":"Discover how to harness the Origin Private File System with RxDB\'s OPFS RxStorage for unrivaled performance and security in client-side data storage.","sidebar":"tutorialSidebar"},"rx-storage-performance":{"id":"rx-storage-performance","title":"\ud83d\udcc8 Discover RxDB Storage Benchmarks","description":"Explore real-world benchmarks comparing RxDB\'s persistent and semi-persistent storages. Discover which storage option delivers the fastest performance.","sidebar":"tutorialSidebar"},"rx-storage-pouchdb":{"id":"rx-storage-pouchdb","title":"PouchDB RxStorage - Migrate for Better Performance","description":"Discover why PouchDB RxStorage is deprecated in RxDB. Learn its legacy, performance drawbacks, and how to upgrade to a faster solution."},"rx-storage-remote":{"id":"rx-storage-remote","title":"Remote RxStorage","description":"The Remote RxStorage is made to use a remote storage and communicate with it over an asynchronous message channel.","sidebar":"tutorialSidebar"},"rx-storage-sharding":{"id":"rx-storage-sharding","title":"Sharding RxStorage \ud83d\udc51","description":"With the sharding plugin, you can improve the write and query times of some RxStorage implementations.","sidebar":"tutorialSidebar"},"rx-storage-shared-worker":{"id":"rx-storage-shared-worker","title":"Boost Performance with SharedWorker RxStorage","description":"Tap into single-instance storage with RxDB\'s SharedWorker. Improve efficiency, cut duplication, and keep your app lightning-fast across tabs.","sidebar":"tutorialSidebar"},"rx-storage-sqlite":{"id":"rx-storage-sqlite","title":"RxDB SQLite RxStorage for Hybrid Apps","description":"Unlock seamless persistence with SQLite RxStorage. Explore usage in hybrid apps, compare performance, and leverage advanced features like attachments.","sidebar":"tutorialSidebar"},"rx-storage-worker":{"id":"rx-storage-worker","title":"Turbocharge RxDB with Worker RxStorage","description":"Offload RxDB queries to WebWorkers or Worker Threads, freeing the main thread and boosting performance. Experience smoother apps with Worker RxStorage.","sidebar":"tutorialSidebar"},"rxdb-tradeoffs":{"id":"rxdb-tradeoffs","title":"RxDB Tradeoffs - Why NoSQL Triumphs on the Client","description":"Uncover RxDB\'s approach to modern database needs. From JSON-based queries to conflict handling without transactions, learn RxDB\'s unique tradeoffs."},"schema-validation":{"id":"schema-validation","title":"Schema Validation","description":"RxDB has multiple validation implementations that can be used to ensure that your document data is always matching the provided JSON","sidebar":"tutorialSidebar"},"slow-indexeddb":{"id":"slow-indexeddb","title":"Solving IndexedDB Slowness for Seamless Apps","description":"Struggling with IndexedDB performance? Discover hidden bottlenecks, advanced tuning techniques, and next-gen storage like the File System Access API.","sidebar":"tutorialSidebar"},"third-party-plugins":{"id":"third-party-plugins","title":"Boost Your RxDB with Powerful Third-Party Plugins","description":"Unleash RxDB\'s full power! Explore third-party plugins for advanced hooks, text search, Laravel Orion, Supabase replication, and more.","sidebar":"tutorialSidebar"},"transactions-conflicts-revisions":{"id":"transactions-conflicts-revisions","title":"Transactions, Conflicts and Revisions","description":"Learn RxDB\'s approach to local and replication conflicts. Discover how incremental writes and custom handlers keep your app stable and efficient.","sidebar":"tutorialSidebar"},"tutorials/typescript":{"id":"tutorials/typescript","title":"TypeScript Setup","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide.","sidebar":"tutorialSidebar"},"why-nosql":{"id":"why-nosql","title":"Why NoSQL Powers Modern UI Apps","description":"Discover how NoSQL enables offline-first UI apps. Learn about easy replication, conflict resolution, and why relational data isn\'t always necessary.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/22dd74f7.fe89e1af.js b/docs/assets/js/22dd74f7.fe89e1af.js new file mode 100644 index 00000000000..c8a1a619752 --- /dev/null +++ b/docs/assets/js/22dd74f7.fe89e1af.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[1567],{5226:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Getting Started with RxDB","collapsed":false,"items":[{"type":"link","label":"Overview","href":"/overview.html","docId":"overview","unlisted":false},{"type":"link","label":"\ud83d\ude80 Quickstart","href":"/quickstart.html","docId":"quickstart","unlisted":false},{"type":"link","label":"Installation","href":"/install.html","docId":"install","unlisted":false},{"type":"link","label":"Development Mode","href":"/dev-mode.html","docId":"dev-mode","unlisted":false},{"type":"link","label":"TypeScript Setup","href":"/tutorials/typescript.html","docId":"tutorials/typescript","unlisted":false}],"collapsible":true},{"type":"category","label":"Core Entities","collapsed":false,"items":[{"type":"link","label":"RxDatabase","href":"/rx-database.html","docId":"rx-database","unlisted":false},{"type":"link","label":"RxSchema","href":"/rx-schema.html","docId":"rx-schema","unlisted":false},{"type":"link","label":"RxCollection","href":"/rx-collection.html","docId":"rx-collection","unlisted":false},{"type":"link","label":"RxDocument","href":"/rx-document.html","docId":"rx-document","unlisted":false},{"type":"link","label":"RxQuery","href":"/rx-query.html","docId":"rx-query","unlisted":false}],"collapsible":true},{"type":"category","label":"\ud83d\udcbe Storages","items":[{"type":"link","label":"RxStorage Overview","href":"/rx-storage.html","docId":"rx-storage","unlisted":false},{"type":"link","label":"Dexie.js","href":"/rx-storage-dexie.html","docId":"rx-storage-dexie","unlisted":false},{"type":"link","label":"IndexedDB \ud83d\udc51","href":"/rx-storage-indexeddb.html","docId":"rx-storage-indexeddb","unlisted":false},{"type":"link","label":"OPFS \ud83d\udc51","href":"/rx-storage-opfs.html","docId":"rx-storage-opfs","unlisted":false},{"type":"link","label":"Memory","href":"/rx-storage-memory.html","docId":"rx-storage-memory","unlisted":false},{"type":"link","label":"SQLite \ud83d\udc51","href":"/rx-storage-sqlite.html","docId":"rx-storage-sqlite","unlisted":false},{"type":"link","label":"Filesystem Node \ud83d\udc51","href":"/rx-storage-filesystem-node.html","docId":"rx-storage-filesystem-node","unlisted":false},{"type":"link","label":"MongoDB","href":"/rx-storage-mongodb.html","docId":"rx-storage-mongodb","unlisted":false},{"type":"link","label":"DenoKV","href":"/rx-storage-denokv.html","docId":"rx-storage-denokv","unlisted":false},{"type":"link","label":"FoundationDB","href":"/rx-storage-foundationdb.html","docId":"rx-storage-foundationdb","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Storage Wrappers","items":[{"type":"link","label":"Schema Validation","href":"/schema-validation.html","docId":"schema-validation","unlisted":false},{"type":"link","label":"Encryption","href":"/encryption.html","docId":"encryption","unlisted":false},{"type":"link","label":"Key Compression","href":"/key-compression.html","docId":"key-compression","unlisted":false},{"type":"link","label":"Logger \ud83d\udc51","href":"/logger.html","docId":"logger","unlisted":false},{"type":"link","label":"Remote RxStorage","href":"/rx-storage-remote.html","docId":"rx-storage-remote","unlisted":false},{"type":"link","label":"Worker RxStorage \ud83d\udc51","href":"/rx-storage-worker.html","docId":"rx-storage-worker","unlisted":false},{"type":"link","label":"SharedWorker RxStorage \ud83d\udc51","href":"/rx-storage-shared-worker.html","docId":"rx-storage-shared-worker","unlisted":false},{"type":"link","label":"Memory Mapped RxStorage \ud83d\udc51","href":"/rx-storage-memory-mapped.html","docId":"rx-storage-memory-mapped","unlisted":false},{"type":"link","label":"Sharding \ud83d\udc51","href":"/rx-storage-sharding.html","docId":"rx-storage-sharding","unlisted":false},{"type":"link","label":"Localstorage Meta Optimizer \ud83d\udc51","href":"/rx-storage-localstorage-meta-optimizer.html","docId":"rx-storage-localstorage-meta-optimizer","unlisted":false},{"type":"link","label":"Electron","href":"/electron.html","docId":"electron","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"\ud83d\udd04 Replication","items":[{"type":"link","label":"\u2699\ufe0f Replication Protocol","href":"/replication.html","docId":"replication","unlisted":false},{"type":"link","label":"HTTP Replication","href":"/replication-http.html","docId":"replication-http","unlisted":false},{"type":"link","label":"RxServer Replication","href":"/replication-server.html","docId":"replication-server","unlisted":false},{"type":"link","label":"GraphQL Replication","href":"/replication-graphql.html","docId":"replication-graphql","unlisted":false},{"type":"link","label":"WebSocket Replication","href":"/replication-websocket.html","docId":"replication-websocket","unlisted":false},{"type":"link","label":"CouchDB Replication","href":"/replication-couchdb.html","docId":"replication-couchdb","unlisted":false},{"type":"link","label":"WebRTC P2P Replication","href":"/replication-webrtc.html","docId":"replication-webrtc","unlisted":false},{"type":"link","label":"Firestore Replication","href":"/replication-firestore.html","docId":"replication-firestore","unlisted":false},{"type":"link","label":"NATS Replication","href":"/replication-nats.html","docId":"replication-nats","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Server","items":[{"type":"link","label":"RxServer","href":"/rx-server.html","docId":"rx-server","unlisted":false},{"type":"link","label":"RxServer Scaling","href":"/rx-server-scaling.html","docId":"rx-server-scaling","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"How RxDB works","items":[{"type":"link","label":"Transactions Conflicts Revisions","href":"/transactions-conflicts-revisions.html","docId":"transactions-conflicts-revisions","unlisted":false},{"type":"link","label":"Query Cache","href":"/query-cache.html","docId":"query-cache","unlisted":false},{"type":"link","label":"Creating Plugins","href":"/plugins.html","docId":"plugins","unlisted":false},{"type":"link","label":"Errors","href":"/errors.html","docId":"errors","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Advanced Features","items":[{"type":"category","label":"Migration","items":[{"type":"link","label":"Schema Migration","href":"/migration-schema.html","docId":"migration-schema","unlisted":false},{"type":"link","label":"Storage Migration","href":"/migration-storage.html","docId":"migration-storage","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Attachments","href":"/rx-attachment.html","docId":"rx-attachment","unlisted":false},{"type":"link","label":"RxPipelines","href":"/rx-pipeline.html","docId":"rx-pipeline","unlisted":false},{"type":"link","label":"Custom Reactivity","href":"/reactivity.html","docId":"reactivity","unlisted":false},{"type":"link","label":"RxState","href":"/rx-state.html","docId":"rx-state","unlisted":false},{"type":"link","label":"Local Documents","href":"/rx-local-document.html","docId":"rx-local-document","unlisted":false},{"type":"link","label":"Cleanup","href":"/cleanup.html","docId":"cleanup","unlisted":false},{"type":"link","label":"Backup","href":"/backup.html","docId":"backup","unlisted":false},{"type":"link","label":"Leader Election","href":"/leader-election.html","docId":"leader-election","unlisted":false},{"type":"link","label":"Middleware","href":"/middleware.html","docId":"middleware","unlisted":false},{"type":"link","label":"CRDT","href":"/crdt.html","docId":"crdt","unlisted":false},{"type":"link","label":"Population","href":"/population.html","docId":"population","unlisted":false},{"type":"link","label":"ORM","href":"/orm.html","docId":"orm","unlisted":false},{"type":"link","label":"Fulltext Search \ud83d\udc51","href":"/fulltext-search.html","docId":"fulltext-search","unlisted":false},{"type":"link","label":"Vector Database","href":"/articles/javascript-vector-database.html","docId":"articles/javascript-vector-database","unlisted":false},{"type":"link","label":"Query Optimizer \ud83d\udc51","href":"/query-optimizer.html","docId":"query-optimizer","unlisted":false},{"type":"link","label":"Third Party Plugins","href":"/third-party-plugins.html","docId":"third-party-plugins","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Performance","items":[{"type":"link","label":"RxStorage Performance","href":"/rx-storage-performance.html","docId":"rx-storage-performance","unlisted":false},{"type":"link","label":"NoSQL Performance Tips","href":"/nosql-performance-tips.html","docId":"nosql-performance-tips","unlisted":false},{"type":"link","label":"Slow IndexedDB","href":"/slow-indexeddb.html","docId":"slow-indexeddb","unlisted":false},{"type":"link","label":"LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite","href":"/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html","docId":"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Releases","items":[{"type":"link","label":"16.0.0","href":"/releases/16.0.0.html","docId":"releases/16.0.0","unlisted":false},{"type":"link","label":"15.0.0","href":"/releases/15.0.0.html","docId":"releases/15.0.0","unlisted":false},{"type":"link","label":"14.0.0","href":"/releases/14.0.0.html","docId":"releases/14.0.0","unlisted":false},{"type":"link","label":"13.0.0","href":"/releases/13.0.0.html","docId":"releases/13.0.0","unlisted":false},{"type":"link","label":"12.0.0","href":"/releases/12.0.0.html","docId":"releases/12.0.0","unlisted":false},{"type":"link","label":"11.0.0","href":"/releases/11.0.0.html","docId":"releases/11.0.0","unlisted":false},{"type":"link","label":"10.0.0","href":"/releases/10.0.0.html","docId":"releases/10.0.0","unlisted":false},{"type":"link","label":"9.0.0","href":"/releases/9.0.0.html","docId":"releases/9.0.0","unlisted":false},{"type":"link","label":"8.0.0","href":"/releases/8.0.0.html","docId":"releases/8.0.0","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Articles","items":[{"type":"link","label":"Local First / Offline First","href":"/offline-first.html","docId":"offline-first","unlisted":false},{"type":"link","label":"Downsides of Local First / Offline First","href":"/downsides-of-offline-first.html","docId":"downsides-of-offline-first","unlisted":false},{"type":"link","label":"Why NoSQL Powers Modern UI Apps","href":"/why-nosql.html","docId":"why-nosql","unlisted":false},{"type":"link","label":"RxDB - The Real-Time Database for Node.js","href":"/nodejs-database.html","docId":"nodejs-database","unlisted":false},{"type":"link","label":"Alternatives for realtime local-first JavaScript applications and local databases","href":"/alternatives.html","docId":"alternatives","unlisted":false},{"type":"link","label":"React Native Database - Sync & Store Like a Pro","href":"/react-native-database.html","docId":"react-native-database","unlisted":false},{"type":"link","label":"RxDB as a Database in an Angular Application","href":"/articles/angular-database.html","docId":"articles/angular-database","unlisted":false},{"type":"link","label":"Benefits of RxDB & Browser Databases","href":"/articles/browser-database.html","docId":"articles/browser-database","unlisted":false},{"type":"link","label":"Browser Storage - RxDB as a Database for Browsers","href":"/articles/browser-storage.html","docId":"articles/browser-storage","unlisted":false},{"type":"link","label":"Empower Web Apps with Reactive RxDB Data-base","href":"/articles/data-base.html","docId":"articles/data-base","unlisted":false},{"type":"link","label":"Embedded Database, Real-time Speed - RxDB","href":"/articles/embedded-database.html","docId":"articles/embedded-database","unlisted":false},{"type":"link","label":"Supercharge Flutter Apps with the RxDB Database","href":"/articles/flutter-database.html","docId":"articles/flutter-database","unlisted":false},{"type":"link","label":"RxDB - The Ultimate JS Frontend Database","href":"/articles/frontend-database.html","docId":"articles/frontend-database","unlisted":false},{"type":"link","label":"RxDB In-Memory NoSQL - Supercharge Real-Time Apps","href":"/articles/in-memory-nosql-database.html","docId":"articles/in-memory-nosql-database","unlisted":false},{"type":"link","label":"RxDB - The Perfect Ionic Database","href":"/articles/ionic-database.html","docId":"articles/ionic-database","unlisted":false},{"type":"link","label":"RxDB - Local Ionic Storage with Encryption, Compression & Sync","href":"/articles/ionic-storage.html","docId":"articles/ionic-storage","unlisted":false},{"type":"link","label":"RxDB - The JSON Database Built for JavaScript","href":"/articles/json-database.html","docId":"articles/json-database","unlisted":false},{"type":"link","label":"WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport","href":"/articles/websockets-sse-polling-webrtc-webtransport.html","docId":"articles/websockets-sse-polling-webrtc-webtransport","unlisted":false},{"type":"link","label":"Using localStorage in Modern Applications - A Comprehensive Guide","href":"/articles/localstorage.html","docId":"articles/localstorage","unlisted":false},{"type":"link","label":"Real-Time & Offline - RxDB for Mobile Apps","href":"/articles/mobile-database.html","docId":"articles/mobile-database","unlisted":false},{"type":"link","label":"RxDB as a Database for Progressive Web Apps (PWA)","href":"/articles/progressive-web-app-database.html","docId":"articles/progressive-web-app-database","unlisted":false},{"type":"link","label":"RxDB as a Database for React Applications","href":"/articles/react-database.html","docId":"articles/react-database","unlisted":false},{"type":"link","label":"What Really Is a Realtime Database?","href":"/articles/realtime-database.html","docId":"articles/realtime-database","unlisted":false},{"type":"link","label":"Build Smarter Offline-First Angular Apps - How RxDB Beats IndexedDB Alone","href":"/articles/angular-indexeddb.html","docId":"articles/angular-indexeddb","unlisted":false},{"type":"link","label":"IndexedDB Database in React Apps - The Power of RxDB","href":"/articles/react-indexeddb.html","docId":"articles/react-indexeddb","unlisted":false},{"type":"link","label":"Capacitor Database Guide - SQLite, RxDB & More","href":"/capacitor-database.html","docId":"capacitor-database","unlisted":false},{"type":"link","label":"Electron Database - Storage adapters for SQLite, Filesystem and In-Memory","href":"/electron-database.html","docId":"electron-database","unlisted":false},{"type":"link","label":"Building an Optimistic UI with RxDB","href":"/articles/optimistic-ui.html","docId":"articles/optimistic-ui","unlisted":false},{"type":"link","label":"What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications","href":"/articles/local-database.html","docId":"articles/local-database","unlisted":false},{"type":"link","label":"React Native Encryption and Encrypted Database/Storage","href":"/articles/react-native-encryption.html","docId":"articles/react-native-encryption","unlisted":false},{"type":"link","label":"RxDB as a Database in a Vue.js Application","href":"/articles/vue-database.html","docId":"articles/vue-database","unlisted":false},{"type":"link","label":"IndexedDB Database in Vue Apps - The Power of RxDB","href":"/articles/vue-indexeddb.html","docId":"articles/vue-indexeddb","unlisted":false},{"type":"link","label":"RxDB as a Database in a jQuery Application","href":"/articles/jquery-database.html","docId":"articles/jquery-database","unlisted":false},{"type":"link","label":"RxDB - Firestore Alternative to Sync with Your Own Backend","href":"/articles/firestore-alternative.html","docId":"articles/firestore-alternative","unlisted":false},{"type":"link","label":"RxDB - Firebase Realtime Database Alternative to Sync With Your Own Backend","href":"/articles/firebase-realtime-database-alternative.html","docId":"articles/firebase-realtime-database-alternative","unlisted":false},{"type":"link","label":"RxDB \u2013 The Ultimate Offline Database with Sync and Encryption","href":"/articles/offline-database.html","docId":"articles/offline-database","unlisted":false},{"type":"link","label":"Zero Latency Local First Apps with RxDB \u2013 Sync, Encryption and Compression","href":"/articles/zero-latency-local-first.html","docId":"articles/zero-latency-local-first","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Contribute & Innovate with RxDB","href":"/contribution.html","docId":"contribute","unlisted":false},{"type":"category","label":"Contact","items":[{"type":"link","label":"Consulting","href":"/consulting/"},{"type":"link","label":"Discord","href":"/chat/","customProps":{"target":"_blank"}},{"type":"link","label":"LinkedIn","href":"https://www.linkedin.com/company/rxdb/"}],"collapsed":true,"collapsible":true}]},"docs":{"adapters":{"id":"adapters","title":"PouchDB Adapters","description":"When you use PouchDB RxStorage, there are many adapters that define where the data has to be stored."},"alternatives":{"id":"alternatives","title":"Alternatives for realtime local-first JavaScript applications and local databases","description":"Explore real-time, local-first JS alternatives to RxDB. Compare Firebase, Meteor, AWS, CouchDB, and more for robust, seamless web/mobile app development.","sidebar":"tutorialSidebar"},"articles/angular-database":{"id":"articles/angular-database","title":"RxDB as a Database in an Angular Application","description":"Level up your Angular projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/angular-indexeddb":{"id":"articles/angular-indexeddb","title":"Build Smarter Offline-First Angular Apps - How RxDB Beats IndexedDB Alone","description":"Discover how to harness IndexedDB in Angular with RxDB for robust offline apps. Learn reactive queries, advanced features, and more.","sidebar":"tutorialSidebar"},"articles/browser-database":{"id":"articles/browser-database","title":"Benefits of RxDB & Browser Databases","description":"Find out why RxDB is the go-to solution for browser databases. See how it boosts performance, simplifies replication, and powers real-time UIs.","sidebar":"tutorialSidebar"},"articles/browser-storage":{"id":"articles/browser-storage","title":"Browser Storage - RxDB as a Database for Browsers","description":"Explore RxDB for browser storage its advantages, limitations, and why it outperforms SQL databases in web applications for enhanced efficiency","sidebar":"tutorialSidebar"},"articles/data-base":{"id":"articles/data-base","title":"Empower Web Apps with Reactive RxDB Data-base","description":"Explore RxDB\'s reactive data-base solution for web and mobile. Enable offline-first experiences, real-time syncing, and secure data handling with ease.","sidebar":"tutorialSidebar"},"articles/embedded-database":{"id":"articles/embedded-database","title":"Embedded Database, Real-time Speed - RxDB","description":"Unleash the power of embedded databases with RxDB. Explore real-time replication, offline access, and reactive queries for modern JavaScript apps.","sidebar":"tutorialSidebar"},"articles/firebase-realtime-database-alternative":{"id":"articles/firebase-realtime-database-alternative","title":"RxDB - Firebase Realtime Database Alternative to Sync With Your Own Backend","description":"Looking for a Firebase Realtime Database alternative? RxDB offers a fully offline, vendor-agnostic NoSQL solution with advanced conflict resolution and multi-platform support.","sidebar":"tutorialSidebar"},"articles/firestore-alternative":{"id":"articles/firestore-alternative","title":"RxDB - Firestore Alternative to Sync with Your Own Backend","description":"Looking for a Firestore alternative? RxDB is a local-first, NoSQL database that syncs seamlessly with any backend, offers rich offline capabilities, advanced conflict resolution, and reduces vendor lock-in.","sidebar":"tutorialSidebar"},"articles/flutter-database":{"id":"articles/flutter-database","title":"Supercharge Flutter Apps with the RxDB Database","description":"Harness RxDB\'s reactive database to bring real-time, offline-first data storage and syncing to your next Flutter application.","sidebar":"tutorialSidebar"},"articles/frontend-database":{"id":"articles/frontend-database","title":"RxDB - The Ultimate JS Frontend Database","description":"Discover how RxDB, a powerful JavaScript frontend database, boosts offline access, caching, and real-time updates to supercharge your web apps.","sidebar":"tutorialSidebar"},"articles/ideas":{"id":"articles/ideas","title":"ideas for articles","description":"- storing and searching through 1mio emails in a browser database"},"articles/in-memory-nosql-database":{"id":"articles/in-memory-nosql-database","title":"RxDB In-Memory NoSQL - Supercharge Real-Time Apps","description":"Discover how RxDB\'s in-memory NoSQL engine delivers blazing speed for real-time apps, ensuring responsive experiences and seamless data sync.","sidebar":"tutorialSidebar"},"articles/ionic-database":{"id":"articles/ionic-database","title":"RxDB - The Perfect Ionic Database","description":"Supercharge your Ionic hybrid apps with RxDB\'s offline-first database. Experience real-time sync, top performance, and easy replication.","sidebar":"tutorialSidebar"},"articles/ionic-storage":{"id":"articles/ionic-storage","title":"RxDB - Local Ionic Storage with Encryption, Compression & Sync","description":"The best Ionic storage solution? RxDB empowers your hybrid apps with offline-first capabilities, secure encryption, data compression, and seamless data syncing to any backend.","sidebar":"tutorialSidebar"},"articles/javascript-vector-database":{"id":"articles/javascript-vector-database","title":"JavaScript Vector Database that runs locally and works offline","description":"Create a blazing-fast vector database in JavaScript. Leverage RxDB and transformers.js for instant, offline semantic search - no servers required!","sidebar":"tutorialSidebar"},"articles/jquery-database":{"id":"articles/jquery-database","title":"RxDB as a Database in a jQuery Application","description":"Level up your jQuery-based projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/json-database":{"id":"articles/json-database","title":"RxDB - The JSON Database Built for JavaScript","description":"Experience a powerful JSON database with RxDB, built for JavaScript. Store, sync, and compress your data seamlessly across web and mobile apps.","sidebar":"tutorialSidebar"},"articles/local-database":{"id":"articles/local-database","title":"What is a Local Database and Why RxDB is the Best Local Database for JavaScript Applications","description":"An in-depth exploration of local databases and why RxDB excels as a local-first solution for JavaScript applications.","sidebar":"tutorialSidebar"},"articles/localstorage":{"id":"articles/localstorage","title":"Using localStorage in Modern Applications - A Comprehensive Guide","description":"This guide explores localStorage in JavaScript web apps, detailing its usage, limitations, and alternatives like IndexedDB and AsyncStorage.","sidebar":"tutorialSidebar"},"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm":{"id":"articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm","title":"LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite","description":"Compare LocalStorage, IndexedDB, Cookies, OPFS, and WASM-SQLite for web storage, performance, limits, and best practices for modern web apps.","sidebar":"tutorialSidebar"},"articles/mobile-database":{"id":"articles/mobile-database","title":"Real-Time & Offline - RxDB for Mobile Apps","description":"Explore RxDB as your reliable mobile database. Enjoy offline-first capabilities, real-time sync, and seamless integration for hybrid app development.","sidebar":"tutorialSidebar"},"articles/offline-database":{"id":"articles/offline-database","title":"RxDB \u2013 The Ultimate Offline Database with Sync and Encryption","description":"Discover how RxDB serves as a powerful offline database, offering real-time synchronization, secure encryption, and an offline-first approach for modern web and mobile apps.","sidebar":"tutorialSidebar"},"articles/optimistic-ui":{"id":"articles/optimistic-ui","title":"Building an Optimistic UI with RxDB","description":"Learn how to build an Optimistic UI with RxDB for instant and reliable UI updates on user interactions","sidebar":"tutorialSidebar"},"articles/progressive-web-app-database":{"id":"articles/progressive-web-app-database","title":"RxDB as a Database for Progressive Web Apps (PWA)","description":"Discover how RxDB supercharges Progressive Web Apps with real-time sync, offline-first capabilities, and lightning-fast data handling.","sidebar":"tutorialSidebar"},"articles/react-database":{"id":"articles/react-database","title":"RxDB as a Database for React Applications","description":"earn how the RxDB database supercharges React apps with offline access, real-time updates, and smooth data flow. Boost performance and engagement.","sidebar":"tutorialSidebar"},"articles/react-indexeddb":{"id":"articles/react-indexeddb","title":"IndexedDB Database in React Apps - The Power of RxDB","description":"Discover how RxDB simplifies IndexedDB in React, offering reactive queries, offline-first capability, encryption, compression, and effortless integration.","sidebar":"tutorialSidebar"},"articles/react-native-encryption":{"id":"articles/react-native-encryption","title":"React Native Encryption and Encrypted Database/Storage","description":"Secure your React Native app with RxDB encryption. Learn why it matters, how to implement encrypted databases, and best practices to protect user data.","sidebar":"tutorialSidebar"},"articles/realtime-database":{"id":"articles/realtime-database","title":"What Really Is a Realtime Database?","description":"Discover how RxDB merges realtime replication and dynamic updates to deliver seamless data sync across browsers, devices, and servers - instantly.","sidebar":"tutorialSidebar"},"articles/vue-database":{"id":"articles/vue-database","title":"RxDB as a Database in a Vue.js Application","description":"Level up your Vue projects with RxDB. Build real-time, resilient, and responsive apps powered by a reactive NoSQL database right in the browser.","sidebar":"tutorialSidebar"},"articles/vue-indexeddb":{"id":"articles/vue-indexeddb","title":"IndexedDB Database in Vue Apps - The Power of RxDB","description":"Learn how RxDB simplifies IndexedDB in Vue, offering reactive queries, offline-first capabilities, encryption, compression, and effortless integration.","sidebar":"tutorialSidebar"},"articles/websockets-sse-polling-webrtc-webtransport":{"id":"articles/websockets-sse-polling-webrtc-webtransport","title":"WebSockets vs Server-Sent-Events vs Long-Polling vs WebRTC vs WebTransport","description":"Learn the unique benefits and pitfalls of each real-time tech. Make informed decisions on WebSockets, SSE, Polling, WebRTC, and WebTransport.","sidebar":"tutorialSidebar"},"articles/zero-latency-local-first":{"id":"articles/zero-latency-local-first","title":"Zero Latency Local First Apps with RxDB \u2013 Sync, Encryption and Compression","description":"Build blazing-fast, zero-latency local first apps with RxDB. Gain instant UI responses, robust offline capabilities, end-to-end encryption, and data compression for streamlined performance.","sidebar":"tutorialSidebar"},"backup":{"id":"backup","title":"Backup","description":"Easily back up your RxDB database to JSON files and attachments on the filesystem with the Backup Plugin - ensuring reliable Node.js data protection.","sidebar":"tutorialSidebar"},"capacitor-database":{"id":"capacitor-database","title":"Capacitor Database Guide - SQLite, RxDB & More","description":"Explore Capacitor\'s top data storage solutions - from key-value to real-time databases. Compare SQLite, RxDB, and more in this in-depth guide.","sidebar":"tutorialSidebar"},"cleanup":{"id":"cleanup","title":"Cleanup","description":"Optimize storage and speed up queries with RxDB\'s Cleanup Plugin, automatically removing old deleted docs while preserving replication states.","sidebar":"tutorialSidebar"},"contribute":{"id":"contribute","title":"Contribute & Innovate with RxDB","description":"Got a fix or fresh idea? Learn how to contribute to RxDB, run tests, and shape the future of this cutting-edge NoSQL database for JavaScript.","sidebar":"tutorialSidebar"},"crdt":{"id":"crdt","title":"CRDT - Conflict-free replicated data type Database","description":"Learn how RxDB\'s CRDT Plugin resolves document conflicts automatically in distributed systems, ensuring seamless merges and consistent data.","sidebar":"tutorialSidebar"},"data-migration":{"id":"data-migration","title":"Data Migration","description":"This documentation page has been moved to here"},"dev-mode":{"id":"dev-mode","title":"Development Mode","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production.","sidebar":"tutorialSidebar"},"downsides-of-offline-first":{"id":"downsides-of-offline-first","title":"Downsides of Local First / Offline First","description":"Discover the hidden pitfalls of local-first apps. Learn about storage limits, conflicts, and real-time illusions before building your offline solution.","sidebar":"tutorialSidebar"},"electron":{"id":"electron","title":"Seamless Electron Storage with RxDB","description":"Use the RxDB Electron Plugin to share data between main and renderer processes. Enjoy quick queries, real-time sync, and robust offline support.","sidebar":"tutorialSidebar"},"electron-database":{"id":"electron-database","title":"Electron Database - Storage adapters for SQLite, Filesystem and In-Memory","description":"Harness the database power of SQLite, Filesystem, and in-memory storage in Electron with RxDB. Build fast, offline-first apps that sync in real time.","sidebar":"tutorialSidebar"},"encryption":{"id":"encryption","title":"Encryption","description":"Explore RxDB\'s \ud83d\udd12 encryption plugin for enhanced data security in web and native apps, featuring password-based encryption and secure storage.","sidebar":"tutorialSidebar"},"errors":{"id":"errors","title":"Error Messages","description":"Learn how RxDB throws RxErrors with codes and parameters. Keep builds lean, yet unveil full messages in development via the DevMode plugin.","sidebar":"tutorialSidebar"},"fulltext-search":{"id":"fulltext-search","title":"Fulltext Search \ud83d\udc51","description":"Master local fulltext search with RxDB\'s FlexSearch plugin. Enjoy real-time indexing, efficient queries, and offline-first support made easy.","sidebar":"tutorialSidebar"},"install":{"id":"install","title":"Installation","description":"Learn how to install RxDB via npm, configure polyfills, and fix global variable errors in Angular or Webpack for a seamless setup.","sidebar":"tutorialSidebar"},"key-compression":{"id":"key-compression","title":"Key Compression","description":"With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.","sidebar":"tutorialSidebar"},"leader-election":{"id":"leader-election","title":"Leader Election","description":"RxDB comes with a leader-election which elects a leading instance between different instances in the same javascript runtime.","sidebar":"tutorialSidebar"},"logger":{"id":"logger","title":"RxDB Logger Plugin - Track & Optimize","description":"Take control of your RxDatabase logs. Monitor every write, query, or attachment retrieval to swiftly diagnose and fix performance bottlenecks.","sidebar":"tutorialSidebar"},"middleware":{"id":"middleware","title":"Streamlined RxDB Middleware","description":"Enhance your RxDB workflow with pre and post hooks. Quickly add custom validations, triggers, and events to streamline your asynchronous operations.","sidebar":"tutorialSidebar"},"migration-schema":{"id":"migration-schema","title":"Seamless Schema Data Migration with RxDB","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly.","sidebar":"tutorialSidebar"},"migration-storage":{"id":"migration-storage","title":"Migration Storage","description":"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:","sidebar":"tutorialSidebar"},"nodejs-database":{"id":"nodejs-database","title":"RxDB - The Real-Time Database for Node.js","description":"Discover how RxDB brings flexible, reactive NoSQL to Node.js. Scale effortlessly, persist data, and power your server-side apps with ease.","sidebar":"tutorialSidebar"},"nosql-performance-tips":{"id":"nosql-performance-tips","title":"RxDB NoSQL Performance Tips","description":"Skyrocket your NoSQL speed with RxDB tips. Learn about bulk writes, optimized queries, and lean plugin usage for peak performance.","sidebar":"tutorialSidebar"},"offline-first":{"id":"offline-first","title":"Local First / Offline First","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency.","sidebar":"tutorialSidebar"},"orm":{"id":"orm","title":"ORM","description":"Like mongoose, RxDB has ORM-capabilities which can be used to add specific behavior to documents and collections.","sidebar":"tutorialSidebar"},"overview":{"id":"overview","title":"RxDB Docs","description":"RxDB Documentation Overview","sidebar":"tutorialSidebar"},"plugins":{"id":"plugins","title":"Creating Plugins","description":"Creating your own plugin is very simple. A plugin is basically a javascript-object which overwrites or extends RxDB\'s internal classes, prototypes, and hooks.","sidebar":"tutorialSidebar"},"population":{"id":"population","title":"Populate and Link Docs in RxDB","description":"Learn how to reference and link documents across collections in RxDB. Discover easy population without joins and handle complex relationships.","sidebar":"tutorialSidebar"},"query-cache":{"id":"query-cache","title":"Efficient RxDB Queries via Query Cache","description":"Learn how RxDB\'s Query Cache boosts performance by reusing queries. Discover its default replacement policy and how to define your own.","sidebar":"tutorialSidebar"},"query-optimizer":{"id":"query-optimizer","title":"Optimize Client-Side Queries with RxDB","description":"Harness real-world data to fine-tune queries. The build-time RxDB Optimizer finds the perfect index, boosting query speed in any environment.","sidebar":"tutorialSidebar"},"quickstart":{"id":"quickstart","title":"\ud83d\ude80 Quickstart","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing.","sidebar":"tutorialSidebar"},"react-native-database":{"id":"react-native-database","title":"React Native Database - Sync & Store Like a Pro","description":"Discover top React Native local database solutions - AsyncStorage, SQLite, RxDB, and more. Build offline-ready apps for iOS, Android, and Windows with easy sync.","sidebar":"tutorialSidebar"},"reactivity":{"id":"reactivity","title":"Signals & Custom Reactivity with RxDB","description":"Level up reactivity with Angular signals, Vue refs, or Preact signals in RxDB. Learn how to integrate custom reactivity to power your dynamic UI.","sidebar":"tutorialSidebar"},"releases/10.0.0":{"id":"releases/10.0.0","title":"RxDB 10.0.0 - Built for the Future","description":"Experience faster, future-proof data handling in RxDB 10.0. Explore new storage interfaces, composite keys, and major performance upgrades.","sidebar":"tutorialSidebar"},"releases/11.0.0":{"id":"releases/11.0.0","title":"RxDB 11 - WebWorker Support & More","description":"RxDB 11.0 brings Worker-based storage for multi-core performance gains. Explore the major changes and migrate seamlessly to harness new speeds.","sidebar":"tutorialSidebar"},"releases/12.0.0":{"id":"releases/12.0.0","title":"RxDB 12.0.0 - Clean, Lean & Mean","description":"Upgrade to RxDB 12.0.0 for blazing-fast queries, streamlined replication, and better index usage. Explore new features and power up your app.","sidebar":"tutorialSidebar"},"releases/13.0.0":{"id":"releases/13.0.0","title":"RxDB 13.0.0 - A New Era of Replication","description":"Discover RxDB 13.0\'s brand-new replication protocol, faster performance, and real-time collaboration for a seamless offline-first experience.","sidebar":"tutorialSidebar"},"releases/14.0.0":{"id":"releases/14.0.0","title":"RxDB 14.0 - Major Changes & New Features","description":"Discover RxDB 14.0, a major release packed with API changes, improved performance, and streamlined storage, ensuring faster data operations than ever.","sidebar":"tutorialSidebar"},"releases/15.0.0":{"id":"releases/15.0.0","title":"RxDB 15.0.0 - Major Migration Overhaul","description":"Discover RxDB 15.0.0, featuring new migration strategies, replication improvements, and lightning-fast performance to supercharge your app.","sidebar":"tutorialSidebar"},"releases/16.0.0":{"id":"releases/16.0.0","title":"RxDB 16.0.0 - Efficiency Redefined","description":"Meet RxDB 16.0.0 - major refactorings, improved performance, and easy migrations. Experience a better, faster, and more stable database solution today.","sidebar":"tutorialSidebar"},"releases/8.0.0":{"id":"releases/8.0.0","title":"Meet RxDB 8.0.0 - New Defaults & Performance","description":"Discover how RxDB 8.0.0 boosts performance, simplifies schema handling, and streamlines reactive data updates for modern apps.","sidebar":"tutorialSidebar"},"releases/9.0.0":{"id":"releases/9.0.0","title":"RxDB 9.0.0 - Faster & Simpler","description":"Discover RxDB 9.0.0\'s streamlined plugins, top-level schema definitions, and improved dev-mode. Experience a simpler, faster real-time database.","sidebar":"tutorialSidebar"},"replication":{"id":"replication","title":"\u2699\ufe0f Replication Protocol","description":"Replicate data in real-time with RxDB\'s offline-first protocol. Enjoy efficient syncing, conflict resolution, and advanced multi-tab support.","sidebar":"tutorialSidebar"},"replication-couchdb":{"id":"replication-couchdb","title":"RxDB\'s CouchDB Replication Plugin","description":"Replicate your RxDB collections with CouchDB the fast way. Enjoy faster sync, easier conflict handling, and flexible storage using this modern plugin.","sidebar":"tutorialSidebar"},"replication-firestore":{"id":"replication-firestore","title":"Smooth Firestore Sync for Offline Apps","description":"Leverage RxDB to enable real-time, offline-first replication with Firestore. Cut cloud costs, resolve conflicts, and speed up your app.","sidebar":"tutorialSidebar"},"replication-graphql":{"id":"replication-graphql","title":"GraphQL Replication","description":"The GraphQL replication provides handlers for GraphQL to run replication with GraphQL as the transportation layer.","sidebar":"tutorialSidebar"},"replication-http":{"id":"replication-http","title":"HTTP Replication","description":"Learn how to establish HTTP replication between RxDB clients and a Node.js Express server for data synchronization.","sidebar":"tutorialSidebar"},"replication-nats":{"id":"replication-nats","title":"RxDB & NATS - Realtime Sync","description":"Seamlessly sync your RxDB data with NATS for real-time, two-way replication. Handle conflicts, errors, and retries with ease.","sidebar":"tutorialSidebar"},"replication-p2p":{"id":"replication-p2p","title":"Seamless P2P Data Sync","description":"Discover how replication-webrtc ensures secure P2P data sync and real-time collaboration with RxDB. Explore the future of offline-first apps!"},"replication-server":{"id":"replication-server","title":"RxDB Server Replication","description":"The Server Replication Plugin connects to the replication endpoint of an RxDB Server Replication Endpoint and replicates data between the client and the server.","sidebar":"tutorialSidebar"},"replication-webrtc":{"id":"replication-webrtc","title":"WebRTC P2P Replication with RxDB - Sync Browsers and Devices","description":"Learn to set up peer-to-peer WebRTC replication with RxDB. Bypass central servers and enjoy secure, low-latency data sync across all clients.","sidebar":"tutorialSidebar"},"replication-websocket":{"id":"replication-websocket","title":"Websocket Replication","description":"With the websocket replication plugin, you can spawn a websocket server from a RxDB database in Node.js and replicate with it.","sidebar":"tutorialSidebar"},"rx-attachment":{"id":"rx-attachment","title":"Attachments","description":"Attachments are binary data files that can be attachment to an RxDocument, like a file that is attached to an email.","sidebar":"tutorialSidebar"},"rx-collection":{"id":"rx-collection","title":"Master Data - Create and Manage RxCollections","description":"Discover how to create, manage, and migrate documents in RxCollections. Harness real-time data flows, secure encryption, and powerful performance in RxDB.","sidebar":"tutorialSidebar"},"rx-database":{"id":"rx-database","title":"RxDatabase - The Core of Your Realtime Data","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today.","sidebar":"tutorialSidebar"},"rx-document":{"id":"rx-document","title":"RxDocument","description":"Master RxDB\'s RxDocument - Insert, find, update, remove, and more for streamlined data handling in modern apps.","sidebar":"tutorialSidebar"},"rx-local-document":{"id":"rx-local-document","title":"Master Local Documents in RxDB","description":"Effortlessly store custom metadata and app settings in RxDB. Learn how Local Documents keep data flexible, secure, and easy to manage.","sidebar":"tutorialSidebar"},"rx-pipeline":{"id":"rx-pipeline","title":"RxPipeline - Automate Data Flows in RxDB","description":"Discover how RxPipeline automates your data workflows. Seamlessly process writes, manage leader election, and ensure crash-safe operations in RxDB.","sidebar":"tutorialSidebar"},"rx-query":{"id":"rx-query","title":"RxQuery","description":"Master RxQuery in RxDB - find, update, remove documents using Mango syntax, chained queries, real-time observations, indexing, and more.","sidebar":"tutorialSidebar"},"rx-schema":{"id":"rx-schema","title":"Design Perfect Schemas in RxDB","description":"Learn how to define, secure, and validate your data in RxDB. Master primary keys, indexes, encryption, and more with the RxSchema approach.","sidebar":"tutorialSidebar"},"rx-server":{"id":"rx-server","title":"RxDB Server - Deploy Your Data","description":"Launch a secure, high-performance server on top of your RxDB database. Enable REST, replication endpoints, and seamless data syncing with RxServer.","sidebar":"tutorialSidebar"},"rx-server-scaling":{"id":"rx-server-scaling","title":"RxServer Scaling - Vertical or Horizontal","description":"Discover vertical and horizontal techniques to boost RxServer. Learn multiple processes, worker threads, and replication for limitless performance.","sidebar":"tutorialSidebar"},"rx-state":{"id":"rx-state","title":"Effortless Reactive State with RxDB\'s RxState","description":"Get real-time, persistent state without the hassle. RxState integrates easily with signals and hooks, ensuring smooth updates across tabs and devices.","sidebar":"tutorialSidebar"},"rx-storage":{"id":"rx-storage","title":"\u2699\ufe0f RxStorage Layer - Choose the Perfect RxDB Storage for Every Use Case","description":"Discover how RxDB\'s modular RxStorage lets you swap engines and unlock top performance, no matter the environment or use case.","sidebar":"tutorialSidebar"},"rx-storage-denokv":{"id":"rx-storage-denokv","title":"DenoKV RxStorage","description":"With the DenoKV RxStorage layer for RxDB, you can run a fully featured NoSQL database on top of the DenoKV API.","sidebar":"tutorialSidebar"},"rx-storage-dexie":{"id":"rx-storage-dexie","title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes.","sidebar":"tutorialSidebar"},"rx-storage-filesystem-node":{"id":"rx-storage-filesystem-node","title":"Blazing-Fast Node Filesystem Storage","description":"Get up and running quickly with RxDB\'s Filesystem Node RxStorage. Store data in JSON, embrace multi-instance support, and enjoy a simpler database.","sidebar":"tutorialSidebar"},"rx-storage-foundationdb":{"id":"rx-storage-foundationdb","title":"RxDB on FoundationDB - Performance at Scale","description":"Combine FoundationDB\'s reliability with RxDB\'s indexing and schema validation. Build scalable apps with faster queries and real-time data.","sidebar":"tutorialSidebar"},"rx-storage-indexeddb":{"id":"rx-storage-indexeddb","title":"Instant Performance with IndexedDB RxStorage","description":"Choose IndexedDB RxStorage for unmatched speed and minimal build size. Perfect for fast-performing apps that demand reliable, lightweight data solutions.","sidebar":"tutorialSidebar"},"rx-storage-localstorage-meta-optimizer":{"id":"rx-storage-localstorage-meta-optimizer","title":"Fastest RxDB Starts - Localstorage Meta Optimizer","description":"Wrap any RxStorage with localStorage metadata to slash initial load by up to 200ms. Unlock speed with this must-have RxDB Premium plugin.","sidebar":"tutorialSidebar"},"rx-storage-lokijs":{"id":"rx-storage-lokijs","title":"Empower RxDB with the LokiJS RxStorage","description":"Discover the lightning-fast LokiJS RxStorage for RxDB. Explore in-memory speed, multi-tab support, and pros & cons of this unique storage solution."},"rx-storage-memory":{"id":"rx-storage-memory","title":"Lightning-Fast Memory Storage for RxDB","description":"Use Memory RxStorage for a high-performance, JavaScript in-memory database. Built for speed, making it perfect for unit tests and rapid prototyping.","sidebar":"tutorialSidebar"},"rx-storage-memory-mapped":{"id":"rx-storage-memory-mapped","title":"Blazing-Fast Memory Mapped RxStorage","description":"Boost your app\'s performance with Memory Mapped RxStorage. Query and write in-memory while seamlessly persisting data to your chosen storage.","sidebar":"tutorialSidebar"},"rx-storage-memory-synced":{"id":"rx-storage-memory-synced","title":"Instant Performance with Memory Synced RxStorage","description":"Accelerate RxDB with in-memory storage replicated to disk. Enjoy instant queries, faster loads, and unstoppable performance for your web apps."},"rx-storage-mongodb":{"id":"rx-storage-mongodb","title":"Unlock MongoDB Power with RxDB","description":"Combine RxDB\'s real-time sync with MongoDB\'s scalability. Harness the MongoDB RxStorage to seamlessly expand your database capabilities.","sidebar":"tutorialSidebar"},"rx-storage-opfs":{"id":"rx-storage-opfs","title":"Supercharged OPFS Database with RxDB","description":"Discover how to harness the Origin Private File System with RxDB\'s OPFS RxStorage for unrivaled performance and security in client-side data storage.","sidebar":"tutorialSidebar"},"rx-storage-performance":{"id":"rx-storage-performance","title":"\ud83d\udcc8 Discover RxDB Storage Benchmarks","description":"Explore real-world benchmarks comparing RxDB\'s persistent and semi-persistent storages. Discover which storage option delivers the fastest performance.","sidebar":"tutorialSidebar"},"rx-storage-pouchdb":{"id":"rx-storage-pouchdb","title":"PouchDB RxStorage - Migrate for Better Performance","description":"Discover why PouchDB RxStorage is deprecated in RxDB. Learn its legacy, performance drawbacks, and how to upgrade to a faster solution."},"rx-storage-remote":{"id":"rx-storage-remote","title":"Remote RxStorage","description":"The Remote RxStorage is made to use a remote storage and communicate with it over an asynchronous message channel.","sidebar":"tutorialSidebar"},"rx-storage-sharding":{"id":"rx-storage-sharding","title":"Sharding RxStorage \ud83d\udc51","description":"With the sharding plugin, you can improve the write and query times of some RxStorage implementations.","sidebar":"tutorialSidebar"},"rx-storage-shared-worker":{"id":"rx-storage-shared-worker","title":"Boost Performance with SharedWorker RxStorage","description":"Tap into single-instance storage with RxDB\'s SharedWorker. Improve efficiency, cut duplication, and keep your app lightning-fast across tabs.","sidebar":"tutorialSidebar"},"rx-storage-sqlite":{"id":"rx-storage-sqlite","title":"RxDB SQLite RxStorage for Hybrid Apps","description":"Unlock seamless persistence with SQLite RxStorage. Explore usage in hybrid apps, compare performance, and leverage advanced features like attachments.","sidebar":"tutorialSidebar"},"rx-storage-worker":{"id":"rx-storage-worker","title":"Turbocharge RxDB with Worker RxStorage","description":"Offload RxDB queries to WebWorkers or Worker Threads, freeing the main thread and boosting performance. Experience smoother apps with Worker RxStorage.","sidebar":"tutorialSidebar"},"rxdb-tradeoffs":{"id":"rxdb-tradeoffs","title":"RxDB Tradeoffs - Why NoSQL Triumphs on the Client","description":"Uncover RxDB\'s approach to modern database needs. From JSON-based queries to conflict handling without transactions, learn RxDB\'s unique tradeoffs."},"schema-validation":{"id":"schema-validation","title":"Schema Validation","description":"RxDB has multiple validation implementations that can be used to ensure that your document data is always matching the provided JSON","sidebar":"tutorialSidebar"},"slow-indexeddb":{"id":"slow-indexeddb","title":"Solving IndexedDB Slowness for Seamless Apps","description":"Struggling with IndexedDB performance? Discover hidden bottlenecks, advanced tuning techniques, and next-gen storage like the File System Access API.","sidebar":"tutorialSidebar"},"third-party-plugins":{"id":"third-party-plugins","title":"Boost Your RxDB with Powerful Third-Party Plugins","description":"Unleash RxDB\'s full power! Explore third-party plugins for advanced hooks, text search, Laravel Orion, Supabase replication, and more.","sidebar":"tutorialSidebar"},"transactions-conflicts-revisions":{"id":"transactions-conflicts-revisions","title":"Transactions, Conflicts and Revisions","description":"Learn RxDB\'s approach to local and replication conflicts. Discover how incremental writes and custom handlers keep your app stable and efficient.","sidebar":"tutorialSidebar"},"tutorials/typescript":{"id":"tutorials/typescript","title":"TypeScript Setup","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide.","sidebar":"tutorialSidebar"},"why-nosql":{"id":"why-nosql","title":"Why NoSQL Powers Modern UI Apps","description":"Discover how NoSQL enables offline-first UI apps. Learn about easy replication, conflict resolution, and why relational data isn\'t always necessary.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/2456d5e0.5aa23ecd.js b/docs/assets/js/2456d5e0.5aa23ecd.js new file mode 100644 index 00000000000..9b2ae9bbcda --- /dev/null +++ b/docs/assets/js/2456d5e0.5aa23ecd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2966],{5643:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"rx-database","title":"RxDatabase - The Core of Your Realtime Data","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today.","source":"@site/docs/rx-database.md","sourceDirName":".","slug":"/rx-database.html","permalink":"/rx-database.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"RxDatabase - The Core of Your Realtime Data","slug":"rx-database.html","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today."},"sidebar":"tutorialSidebar","previous":{"title":"TypeScript Setup","permalink":"/tutorials/typescript.html"},"next":{"title":"RxSchema","permalink":"/rx-schema.html"}}');var s=t(4848),r=t(8453);const i={title:"RxDatabase - The Core of Your Realtime Data",slug:"rx-database.html",description:"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today."},o="RxDatabase",l={},d=[{value:"Creation",id:"creation",level:2},{value:"name",id:"name",level:3},{value:"storage",id:"storage",level:3},{value:"password",id:"password",level:3},{value:"multiInstance",id:"multiinstance",level:3},{value:"eventReduce",id:"eventreduce",level:3},{value:"ignoreDuplicate",id:"ignoreduplicate",level:3},{value:"hashFunction",id:"hashfunction",level:3},{value:"Methods",id:"methods",level:2},{value:"Observe with $",id:"observe-with-",level:3},{value:"exportJSON()",id:"exportjson",level:3},{value:"importJSON()",id:"importjson",level:3},{value:"backup()",id:"backup",level:3},{value:"waitForLeadership()",id:"waitforleadership",level:3},{value:"requestIdlePromise()",id:"requestidlepromise",level:3},{value:"close()",id:"close",level:3},{value:"remove()",id:"remove",level:3},{value:"isRxDatabase",id:"isrxdatabase",level:3}];function c(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.header,{children:(0,s.jsx)(a.h1,{id:"rxdatabase",children:"RxDatabase"})}),"\n",(0,s.jsx)(a.p,{children:"A RxDatabase-Object contains your collections and handles the synchronization of change-events."}),"\n",(0,s.jsx)(a.h2,{id:"creation",children:"Creation"}),"\n",(0,s.jsxs)(a.p,{children:["The database is created by the asynchronous ",(0,s.jsx)(a.code,{children:".createRxDatabase()"})," function of the core RxDB module. It has the following parameters:"]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst db = await createRxDatabase({\n name: 'heroesdb', // <- name\n storage: getRxStorageDexie(), // <- RxStorage\n\n /* Optional parameters: */\n password: 'myPassword', // <- password (optional)\n multiInstance: true, // <- multiInstance (optional, default: true)\n eventReduce: true, // <- eventReduce (optional, default: false)\n cleanupPolicy: {} // <- custom cleanup policy (optional) \n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"name",children:"name"}),"\n",(0,s.jsxs)(a.p,{children:["The database-name is a string which uniquely identifies the database. When two RxDatabases have the same name and use the same ",(0,s.jsx)(a.code,{children:"RxStorage"}),", their data can be assumed as equal and they will share events between each other.\nDepending on the storage or adapter this can also be used to define the filesystem folder of your data."]}),"\n",(0,s.jsx)(a.h3,{id:"storage",children:"storage"}),"\n",(0,s.jsxs)(a.p,{children:["RxDB works on top of an implementation of the ",(0,s.jsx)(a.a,{href:"/rx-storage.html",children:"RxStorage"})," interface. This interface is an abstraction that allows you to use different underlying databases that actually handle the documents. Depending on your use case you might use a different ",(0,s.jsx)(a.code,{children:"storage"})," with different tradeoffs in performance, bundle size or supported runtimes."]}),"\n",(0,s.jsxs)(a.p,{children:["There are many ",(0,s.jsx)(a.code,{children:"RxStorage"})," implementations that can be used depending on the JavaScript environment and performance requirements.\nFor example you can use the ",(0,s.jsx)(a.a,{href:"/rx-storage-dexie.html",children:"Dexie RxStorage"})," in the browser or use the ",(0,s.jsx)(a.a,{href:"/rx-storage-mongodb.html",children:"MongoDB RxStorage"})," in Node.js."]}),"\n",(0,s.jsxs)(a.ul,{children:["\n",(0,s.jsx)(a.li,{children:(0,s.jsx)(a.a,{href:"/rx-storage.html",children:"List of RxStorage implementations"})}),"\n"]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"\n// use the Dexie.js RxStorage that stores data in IndexedDB.\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst dbDexie = await createRxDatabase({\n name: 'mydatabase',\n storage: getRxStorageDexie()\n});\n\n\n// ...or use the MongoDB RxStorage in Node.js.\nimport { getRxStorageMongoDB } from 'rxdb/plugins/storage-mongodb';\n\nconst dbMongo = await createRxDatabase({\n name: 'mydatabase',\n storage: getRxStorageMongoDB({\n connection: 'mongodb://localhost:27017,localhost:27018,localhost:27019'\n })\n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"password",children:"password"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional)"}),"\nIf you want to use encrypted fields in the collections of a database, you have to set a password for it. The password must be a string with at least 12 characters."]}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.a,{href:"/encryption.html",children:"Read more about encryption here"}),"."]}),"\n",(0,s.jsx)(a.h3,{id:"multiinstance",children:"multiInstance"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional=true)"}),"\nWhen you create more than one instance of the same database in a single javascript-runtime, you should set ",(0,s.jsx)(a.code,{children:"multiInstance"})," to ",(0,s.jsx)(a.code,{children:"true"}),". This will enable the event sharing between the two instances. For example when the user has opened multiple browser windows, events will be shared between them so that both windows react to the same changes.\n",(0,s.jsx)(a.code,{children:"multiInstance"})," should be set to ",(0,s.jsx)(a.code,{children:"false"})," when you have single-instances like a single Node.js-process, a react-native-app, a cordova-app or a single-window ",(0,s.jsx)(a.a,{href:"/electron-database.html",children:"electron"})," app which can decrease the startup time because no instance coordination has to be done."]}),"\n",(0,s.jsx)(a.h3,{id:"eventreduce",children:"eventReduce"}),"\n",(0,s.jsx)(a.p,{children:(0,s.jsx)(a.code,{children:"(optional=false)"})}),"\n",(0,s.jsxs)(a.p,{children:["One big benefit of having a realtime database is that big performance optimizations can be done when the database knows a query is observed and the updated results are needed continuously. RxDB uses the ",(0,s.jsx)(a.a,{href:"https://github.com/pubkey/event-reduce",children:"EventReduce Algorithm"})," to optimize observer or recurring queries."]}),"\n",(0,s.jsxs)(a.p,{children:["For better performance, you should always set ",(0,s.jsx)(a.code,{children:"eventReduce: true"}),". This will also be the default in the next major RxDB version."]}),"\n",(0,s.jsx)(a.h3,{id:"ignoreduplicate",children:"ignoreDuplicate"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional=false)"}),"\nIf you create multiple RxDatabase-instances with the same name and same adapter, it's very likely that you have done something wrong.\nTo prevent this common mistake, RxDB will throw an error when you do this.\nIn some rare cases like unit-tests, you want to do this intentional by setting ",(0,s.jsx)(a.code,{children:"ignoreDuplicate"})," to ",(0,s.jsx)(a.code,{children:"true"}),". Because setting ",(0,s.jsx)(a.code,{children:"ignoreDuplicate: true"})," in production will decrease the performance by having multiple instances of the same database, ",(0,s.jsx)(a.code,{children:"ignoreDuplicate"})," is only allowed to be set in ",(0,s.jsx)(a.a,{href:"/dev-mode.html",children:"dev-mode"}),"."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-js",children:"const db1 = await createRxDatabase({\n name: 'heroesdb',\n storage: getRxStorageDexie(),\n ignoreDuplicate: true\n});\nconst db2 = await createRxDatabase({\n name: 'heroesdb',\n storage: getRxStorageDexie(),\n ignoreDuplicate: true // this create-call will not throw because you explicitly allow it\n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"hashfunction",children:"hashFunction"}),"\n",(0,s.jsxs)(a.p,{children:["By default, RxDB will use ",(0,s.jsx)(a.code,{children:"crypto.subtle.digest('SHA-256', data)"})," for hashing. If you need a different hash function or the ",(0,s.jsx)(a.code,{children:"crypto.subtle"})," API is not supported in your JavaScript runtime, you can provide an own hash function instead. A hash function gets a string as input and returns a ",(0,s.jsx)(a.code,{children:"Promise"})," that resolves a string."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-ts",children:"// example hash function that runs in plain JavaScript\nimport { sha256 } from 'ohash';\nfunction myOwnHashFunction(input: string) {\n return Promise.resolve(sha256(input));\n}\nconst db = await createRxDatabase({\n hashFunction: myOwnHashFunction\n /* ... */\n});\n"})}),"\n",(0,s.jsxs)(a.p,{children:["If you get the error message ",(0,s.jsx)(a.code,{children:"TypeError: Cannot read properties of undefined (reading 'digest')"})," this likely means that you are neither running on ",(0,s.jsx)(a.code,{children:"localhost"})," nor on ",(0,s.jsx)(a.code,{children:"https"})," which is why your browser might not allow access to ",(0,s.jsx)(a.code,{children:"crypto.subtle.digest"}),"."]}),"\n",(0,s.jsx)(a.h2,{id:"methods",children:"Methods"}),"\n",(0,s.jsx)(a.h3,{id:"observe-with-",children:"Observe with $"}),"\n",(0,s.jsxs)(a.p,{children:["Calling this will return an ",(0,s.jsx)(a.a,{href:"http://reactivex.io/documentation/observable.html",children:"rxjs-Observable"})," which streams all write events of the ",(0,s.jsx)(a.code,{children:"RxDatabase"}),"."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"myDb.$.subscribe(changeEvent => console.dir(changeEvent));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"exportjson",children:"exportJSON()"}),"\n",(0,s.jsxs)(a.p,{children:["Use this function to create a json-export from every piece of data in every collection of this database. You can pass ",(0,s.jsx)(a.code,{children:"true"})," as a parameter to decrypt the encrypted data-fields of your document."]}),"\n",(0,s.jsxs)(a.p,{children:["Before ",(0,s.jsx)(a.code,{children:"exportJSON()"})," and ",(0,s.jsx)(a.code,{children:"importJSON()"})," can be used, you have to add the ",(0,s.jsx)(a.code,{children:"json-dump"})," plugin."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { addRxPlugin } from 'rxdb';\nimport { RxDBJsonDumpPlugin } from 'rxdb/plugins/json-dump';\naddRxPlugin(RxDBJsonDumpPlugin);\n"})}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"myDatabase.exportJSON()\n .then(json => console.dir(json));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"importjson",children:"importJSON()"}),"\n",(0,s.jsx)(a.p,{children:"To import the json-dumps into your database, use this function."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"// import the dump to the database\nemptyDatabase.importJSON(json)\n .then(() => console.log('done'));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"backup",children:"backup()"}),"\n",(0,s.jsxs)(a.p,{children:["Writes the current (or ongoing) database state to the filesystem. ",(0,s.jsx)(a.a,{href:"/backup.html",children:"Read more"})]}),"\n",(0,s.jsx)(a.h3,{id:"waitforleadership",children:"waitForLeadership()"}),"\n",(0,s.jsxs)(a.p,{children:["Returns a Promise which resolves when the RxDatabase becomes ",(0,s.jsx)(a.a,{href:"/leader-election.html",children:"elected leader"}),"."]}),"\n",(0,s.jsx)(a.h3,{id:"requestidlepromise",children:"requestIdlePromise()"}),"\n",(0,s.jsxs)(a.p,{children:["Returns a promise which resolves when the database is in idle. This works similar to ",(0,s.jsx)(a.a,{href:"https://developer.mozilla.org/de/docs/Web/API/Window/requestIdleCallback",children:"requestIdleCallback"})," but tracks the idle-ness of the database instead of the CPU.\nUse this for semi-important tasks like cleanups which should not affect the speed of important tasks."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"\nmyDatabase.requestIdlePromise().then(() => {\n // this will run at the moment the database has nothing else to do\n myCollection.customCleanupFunction();\n});\n\n// with timeout\nmyDatabase.requestIdlePromise(1000 /* time in ms */).then(() => {\n // this will run at the moment the database has nothing else to do\n // or the timeout has passed\n myCollection.customCleanupFunction();\n});\n\n"})}),"\n",(0,s.jsx)(a.h3,{id:"close",children:"close()"}),"\n",(0,s.jsxs)(a.p,{children:["Closes the databases object-instance. This is to free up memory and stop all observers and replications.\nReturns a ",(0,s.jsx)(a.code,{children:"Promise"})," that resolves when the database is closed.\nClosing a database will not remove the databases data. When you create the database again with ",(0,s.jsx)(a.code,{children:"createRxDatabase()"}),", all data will still be there."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"await myDatabase.close();\n"})}),"\n",(0,s.jsx)(a.h3,{id:"remove",children:"remove()"}),"\n",(0,s.jsx)(a.p,{children:"Wipes all documents from the storage. Use this to free up disc space."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"await myDatabase.remove();\n// database instance is now gone\n\n// You can also clear a database without removing its instance\nimport { removeRxDatabase } from 'rxdb';\nremoveRxDatabase('mydatabasename', 'localstorage');\n"})}),"\n",(0,s.jsx)(a.h3,{id:"isrxdatabase",children:"isRxDatabase"}),"\n",(0,s.jsx)(a.p,{children:"Returns true if the given object is an instance of RxDatabase. Returns false if not."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { isRxDatabase } from 'rxdb';\nconst is = isRxDatabase(myObj);\n"})})]})}function h(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,s.jsx)(a,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,a,t)=>{t.d(a,{R:()=>i,x:()=>o});var n=t(6540);const s={},r=n.createContext(s);function i(e){const a=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(r.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2456d5e0.ec9e7ea4.js b/docs/assets/js/2456d5e0.ec9e7ea4.js deleted file mode 100644 index 624992e6f75..00000000000 --- a/docs/assets/js/2456d5e0.ec9e7ea4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2966],{5643:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"rx-database","title":"RxDatabase - The Core of Your Realtime Data","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today.","source":"@site/docs/rx-database.md","sourceDirName":".","slug":"/rx-database.html","permalink":"/rx-database.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"RxDatabase - The Core of Your Realtime Data","slug":"rx-database.html","description":"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today."},"sidebar":"tutorialSidebar","previous":{"title":"TypeScript Setup","permalink":"/tutorials/typescript.html"},"next":{"title":"RxSchema","permalink":"/rx-schema.html"}}');var s=t(4848),r=t(8453);const i={title:"RxDatabase - The Core of Your Realtime Data",slug:"rx-database.html",description:"Get started with RxDatabase and integrate multiple storages. Learn to create, encrypt, and optimize your realtime database today."},o="RxDatabase",l={},d=[{value:"Creation",id:"creation",level:2},{value:"name",id:"name",level:3},{value:"storage",id:"storage",level:3},{value:"password",id:"password",level:3},{value:"multiInstance",id:"multiinstance",level:3},{value:"eventReduce",id:"eventreduce",level:3},{value:"ignoreDuplicate",id:"ignoreduplicate",level:3},{value:"hashFunction",id:"hashfunction",level:3},{value:"Methods",id:"methods",level:2},{value:"Observe with $",id:"observe-with-",level:3},{value:"exportJSON()",id:"exportjson",level:3},{value:"importJSON()",id:"importjson",level:3},{value:"backup()",id:"backup",level:3},{value:"waitForLeadership()",id:"waitforleadership",level:3},{value:"requestIdlePromise()",id:"requestidlepromise",level:3},{value:"close()",id:"close",level:3},{value:"remove()",id:"remove",level:3},{value:"isRxDatabase",id:"isrxdatabase",level:3}];function c(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.header,{children:(0,s.jsx)(a.h1,{id:"rxdatabase",children:"RxDatabase"})}),"\n",(0,s.jsx)(a.p,{children:"A RxDatabase-Object contains your collections and handles the synchronization of change-events."}),"\n",(0,s.jsx)(a.h2,{id:"creation",children:"Creation"}),"\n",(0,s.jsxs)(a.p,{children:["The database is created by the asynchronous ",(0,s.jsx)(a.code,{children:".createRxDatabase()"})," function of the core RxDB module. It has the following parameters:"]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { createRxDatabase } from 'rxdb';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst db = await createRxDatabase({\n name: 'heroesdb', // <- name\n storage: getRxStorageDexie(), // <- RxStorage\n\n /* Optional parameters: */\n password: 'myPassword', // <- password (optional)\n multiInstance: true, // <- multiInstance (optional, default: true)\n eventReduce: true, // <- eventReduce (optional, default: false)\n cleanupPolicy: {} // <- custom cleanup policy (optional) \n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"name",children:"name"}),"\n",(0,s.jsxs)(a.p,{children:["The database-name is a string which uniquely identifies the database. When two RxDatabases have the same name and use the same ",(0,s.jsx)(a.code,{children:"RxStorage"}),", their data can be assumed as equal and they will share events between each other.\nDepending on the storage or adapter this can also be used to define the filesystem folder of your data."]}),"\n",(0,s.jsx)(a.h3,{id:"storage",children:"storage"}),"\n",(0,s.jsxs)(a.p,{children:["RxDB works on top of an implementation of the ",(0,s.jsx)(a.a,{href:"/rx-storage.html",children:"RxStorage"})," interface. This interface is an abstraction that allows you to use different underlying databases that actually handle the documents. Depending on your use case you might use a different ",(0,s.jsx)(a.code,{children:"storage"})," with different tradeoffs in performance, bundle size or supported runtimes."]}),"\n",(0,s.jsxs)(a.p,{children:["There are many ",(0,s.jsx)(a.code,{children:"RxStorage"})," implementations that can be used depending on the JavaScript environment and performance requirements.\nFor example you can use the ",(0,s.jsx)(a.a,{href:"/rx-storage-dexie.html",children:"Dexie RxStorage"})," in the browser or use the ",(0,s.jsx)(a.a,{href:"/rx-storage-mongodb.html",children:"MongoDB RxStorage"})," in Node.js."]}),"\n",(0,s.jsxs)(a.ul,{children:["\n",(0,s.jsx)(a.li,{children:(0,s.jsx)(a.a,{href:"/rx-storage.html",children:"List of RxStorage implementations"})}),"\n"]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"\n// use the Dexie.js RxStorage that stores data in IndexedDB.\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst dbDexie = await createRxDatabase({\n name: 'mydatabase',\n storage: getRxStorageDexie()\n});\n\n\n// ...or use the MongoDB RxStorage in Node.js.\nimport { getRxStorageMongoDB } from 'rxdb/plugins/storage-mongodb';\n\nconst dbMongo = await createRxDatabase({\n name: 'mydatabase',\n storage: getRxStorageMongoDB({\n connection: 'mongodb://localhost:27017,localhost:27018,localhost:27019'\n })\n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"password",children:"password"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional)"}),"\nIf you want to use encrypted fields in the collections of a database, you have to set a password for it. The password must be a string with at least 12 characters."]}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.a,{href:"/encryption.html",children:"Read more about encryption here"}),"."]}),"\n",(0,s.jsx)(a.h3,{id:"multiinstance",children:"multiInstance"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional=true)"}),"\nWhen you create more than one instance of the same database in a single javascript-runtime, you should set ",(0,s.jsx)(a.code,{children:"multiInstance"})," to ",(0,s.jsx)(a.code,{children:"true"}),". This will enable the event sharing between the two instances. For example when the user has opened multiple browser windows, events will be shared between them so that both windows react to the same changes.\n",(0,s.jsx)(a.code,{children:"multiInstance"})," should be set to ",(0,s.jsx)(a.code,{children:"false"})," when you have single-instances like a single Node.js-process, a react-native-app, a cordova-app or a single-window ",(0,s.jsx)(a.a,{href:"/electron-database.html",children:"electron"})," app which can decrease the startup time because no instance coordination has to be done."]}),"\n",(0,s.jsx)(a.h3,{id:"eventreduce",children:"eventReduce"}),"\n",(0,s.jsx)(a.p,{children:(0,s.jsx)(a.code,{children:"(optional=false)"})}),"\n",(0,s.jsxs)(a.p,{children:["One big benefit of having a realtime database is that big performance optimizations can be done when the database knows a query is observed and the updated results are needed continuously. RxDB uses the ",(0,s.jsx)(a.a,{href:"https://github.com/pubkey/event-reduce",children:"EventReduce Algorithm"})," to optimize observer or recurring queries."]}),"\n",(0,s.jsxs)(a.p,{children:["For better performance, you should always set ",(0,s.jsx)(a.code,{children:"eventReduce: true"}),". This will also be the default in the next major RxDB version."]}),"\n",(0,s.jsx)(a.h3,{id:"ignoreduplicate",children:"ignoreDuplicate"}),"\n",(0,s.jsxs)(a.p,{children:[(0,s.jsx)(a.code,{children:"(optional=false)"}),"\nIf you create multiple RxDatabase-instances with the same name and same adapter, it's very likely that you have done something wrong.\nTo prevent this common mistake, RxDB will throw an error when you do this.\nIn some rare cases like unit-tests, you want to do this intentional by setting ",(0,s.jsx)(a.code,{children:"ignoreDuplicate"})," to ",(0,s.jsx)(a.code,{children:"true"}),". Because setting ",(0,s.jsx)(a.code,{children:"ignoreDuplicate: true"})," in production will decrease the performance by having multiple instances of the same database, ",(0,s.jsx)(a.code,{children:"ignoreDuplicate"})," is only allowed to be set in ",(0,s.jsx)(a.a,{href:"/dev-mode.html",children:"dev-mode"}),"."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-js",children:"const db1 = await createRxDatabase({\n name: 'heroesdb',\n storage: getRxStorageDexie(),\n ignoreDuplicate: true\n});\nconst db2 = await createRxDatabase({\n name: 'heroesdb',\n storage: getRxStorageDexie(),\n ignoreDuplicate: true // this create-call will not throw because you explicitly allow it\n});\n"})}),"\n",(0,s.jsx)(a.h3,{id:"hashfunction",children:"hashFunction"}),"\n",(0,s.jsxs)(a.p,{children:["By default, RxDB will use ",(0,s.jsx)(a.code,{children:"crypto.subtle.digest('SHA-256', data)"})," for hashing. If you need a different hash function or the ",(0,s.jsx)(a.code,{children:"crypto.subtle"})," API is not supported in your JavaScript runtime, you can provide an own hash function instead. A hash function gets a string as input and returns a ",(0,s.jsx)(a.code,{children:"Promise"})," that resolves a string."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-ts",children:"// example hash function that runs in plain JavaScript\nimport { sha256 } from 'ohash';\nfunction myOwnHashFunction(input: string) {\n return Promise.resolve(sha256(input));\n}\nconst db = await createRxDatabase({\n hashFunction: myOwnHashFunction\n /* ... */\n});\n"})}),"\n",(0,s.jsxs)(a.p,{children:["If you get the error message ",(0,s.jsx)(a.code,{children:"TypeError: Cannot read properties of undefined (reading 'digest')"})," this likely means that you are neither running on ",(0,s.jsx)(a.code,{children:"localhost"})," nor on ",(0,s.jsx)(a.code,{children:"https"})," which is why your browser might not allow access to ",(0,s.jsx)(a.code,{children:"crypto.subtle.digest"}),"."]}),"\n",(0,s.jsx)(a.h2,{id:"methods",children:"Methods"}),"\n",(0,s.jsx)(a.h3,{id:"observe-with-",children:"Observe with $"}),"\n",(0,s.jsxs)(a.p,{children:["Calling this will return an ",(0,s.jsx)(a.a,{href:"http://reactivex.io/documentation/observable.html",children:"rxjs-Observable"})," which streams all write events of the ",(0,s.jsx)(a.code,{children:"RxDatabase"}),"."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"myDb.$.subscribe(changeEvent => console.dir(changeEvent));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"exportjson",children:"exportJSON()"}),"\n",(0,s.jsxs)(a.p,{children:["Use this function to create a json-export from every piece of data in every collection of this database. You can pass ",(0,s.jsx)(a.code,{children:"true"})," as a parameter to decrypt the encrypted data-fields of your document."]}),"\n",(0,s.jsxs)(a.p,{children:["Before ",(0,s.jsx)(a.code,{children:"exportJSON()"})," and ",(0,s.jsx)(a.code,{children:"importJSON()"})," can be used, you have to add the ",(0,s.jsx)(a.code,{children:"json-dump"})," plugin."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { addRxPlugin } from 'rxdb';\nimport { RxDBJsonDumpPlugin } from 'rxdb/plugins/json-dump';\naddRxPlugin(RxDBJsonDumpPlugin);\n"})}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"myDatabase.exportJSON()\n .then(json => console.dir(json));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"importjson",children:"importJSON()"}),"\n",(0,s.jsx)(a.p,{children:"To import the json-dumps into your database, use this function."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"// import the dump to the database\nemptyDatabase.importJSON(json)\n .then(() => console.log('done'));\n"})}),"\n",(0,s.jsx)(a.h3,{id:"backup",children:"backup()"}),"\n",(0,s.jsxs)(a.p,{children:["Writes the current (or ongoing) database state to the filesystem. ",(0,s.jsx)(a.a,{href:"/backup.html",children:"Read more"})]}),"\n",(0,s.jsx)(a.h3,{id:"waitforleadership",children:"waitForLeadership()"}),"\n",(0,s.jsxs)(a.p,{children:["Returns a Promise which resolves when the RxDatabase becomes ",(0,s.jsx)(a.a,{href:"/leader-election.html",children:"elected leader"}),"."]}),"\n",(0,s.jsx)(a.h3,{id:"requestidlepromise",children:"requestIdlePromise()"}),"\n",(0,s.jsxs)(a.p,{children:["Returns a promise which resolves when the database is in idle. This works similar to ",(0,s.jsx)(a.a,{href:"https://developer.mozilla.org/de/docs/Web/API/Window/requestIdleCallback",children:"requestIdleCallback"})," but tracks the idle-ness of the database instead of the CPU.\nUse this for semi-important tasks like cleanups which should not affect the speed of important tasks."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"\nmyDatabase.requestIdlePromise().then(() => {\n // this will run at the moment the database has nothing else to do\n myCollection.customCleanupFunction();\n});\n\n// with timeout\nmyDatabase.requestIdlePromise(1000 /* time in ms */).then(() => {\n // this will run at the moment the database has nothing else to do\n // or the timeout has passed\n myCollection.customCleanupFunction();\n});\n\n"})}),"\n",(0,s.jsx)(a.h3,{id:"close",children:"close()"}),"\n",(0,s.jsxs)(a.p,{children:["Closes the databases object-instance. This is to free up memory and stop all observers and replications.\nReturns a ",(0,s.jsx)(a.code,{children:"Promise"})," that resolves when the database is closed.\nClosing a database will not remove the databases data. When you create the database again with ",(0,s.jsx)(a.code,{children:"createRxDatabase()"}),", all data will still be there."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"await myDatabase.close();\n"})}),"\n",(0,s.jsx)(a.h3,{id:"remove",children:"remove()"}),"\n",(0,s.jsx)(a.p,{children:"Wipes all documents from the storage. Use this to free up disc space."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"await myDatabase.remove();\n// database instance is now gone\n\n// You can also clear a database without removing its instance\nimport { removeRxDatabase } from 'rxdb';\nremoveRxDatabase('mydatabasename', 'localstorage');\n"})}),"\n",(0,s.jsx)(a.h3,{id:"isrxdatabase",children:"isRxDatabase"}),"\n",(0,s.jsx)(a.p,{children:"Returns true if the given object is an instance of RxDatabase. Returns false if not."}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-javascript",children:"import { isRxDatabase } from 'rxdb';\nconst is = isRxDatabase(myObj);\n"})})]})}function h(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,s.jsx)(a,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,a,t)=>{t.d(a,{R:()=>i,x:()=>o});var n=t(6540);const s={},r=n.createContext(s);function i(e){const a=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(r.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2efd0200.5499b9c8.js b/docs/assets/js/2efd0200.5499b9c8.js new file mode 100644 index 00000000000..4a8e627cecc --- /dev/null +++ b/docs/assets/js/2efd0200.5499b9c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4132],{1780:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>p});const s=JSON.parse('{"id":"tutorials/typescript","title":"TypeScript Setup","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide.","source":"@site/docs/tutorials/typescript.md","sourceDirName":"tutorials","slug":"/tutorials/typescript.html","permalink":"/tutorials/typescript.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"TypeScript Setup","slug":"typescript.html","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide."},"sidebar":"tutorialSidebar","previous":{"title":"Development Mode","permalink":"/dev-mode.html"},"next":{"title":"RxDatabase","permalink":"/rx-database.html"}}');var o=n(4848),r=n(8453),a=n(7580);const i={title:"TypeScript Setup",slug:"typescript.html",description:"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide."},c="Using RxDB with TypeScript",l={},p=[{value:"Declare the types",id:"declare-the-types",level:2},{value:"Create the base document type",id:"create-the-base-document-type",level:2},{value:"Types for the ORM methods",id:"types-for-the-orm-methods",level:2},{value:"Create RxDocument Type",id:"create-rxdocument-type",level:2},{value:"Create RxCollection Type",id:"create-rxcollection-type",level:2},{value:"Create RxDatabase Type",id:"create-rxdatabase-type",level:2},{value:"Using the types",id:"using-the-types",level:2},{value:"Known Problems",id:"known-problems",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"using-rxdb-with-typescript",children:"Using RxDB with TypeScript"})}),"\n",(0,o.jsx)(t.p,{children:"In this tutorial you will learn how to use RxDB with TypeScript.\nWe will create a basic database with one collection and several ORM-methods, fully typed!"}),"\n",(0,o.jsx)(t.p,{children:"RxDB directly comes with its typings and you do not have to install anything else, however the latest version of RxDB requires that you are using Typescript v3.8 or newer.\nOur way to go is"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"First define what the documents look like"}),"\n",(0,o.jsx)(t.li,{children:"Then define what the collections look like"}),"\n",(0,o.jsx)(t.li,{children:"Then define what the database looks like"}),"\n"]}),"\n",(0,o.jsxs)(a.g,{children:[(0,o.jsx)(t.h2,{id:"declare-the-types",children:"Declare the types"}),(0,o.jsx)(t.p,{children:"First you import the types from RxDB."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"import {\n createRxDatabase,\n RxDatabase,\n RxCollection,\n RxJsonSchema,\n RxDocument,\n} from 'rxdb/plugins/core';\n"})}),(0,o.jsx)(t.h2,{id:"create-the-base-document-type",children:"Create the base document type"}),(0,o.jsx)(t.p,{children:"First we have to define the TypeScript type of the documents of a collection:"}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Option A"}),": Create the document type from the schema"]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"import {\n toTypedRxJsonSchema,\n ExtractDocumentTypeFromTypedRxJsonSchema,\n RxJsonSchema\n} from 'rxdb';\nexport const heroSchemaLiteral = {\n title: 'hero schema',\n description: 'describes a human being',\n version: 0,\n keyCompression: true,\n primaryKey: 'passportId',\n type: 'object',\n properties: {\n passportId: {\n type: 'string',\n maxLength: 100 // <- the primary key must have set maxLength\n },\n firstName: {\n type: 'string'\n },\n lastName: {\n type: 'string'\n },\n age: {\n type: 'integer'\n }\n },\n required: ['firstName', 'lastName', 'passportId'],\n indexes: ['firstName']\n} as const; // <- It is important to set 'as const' to preserve the literal type\nconst schemaTyped = toTypedRxJsonSchema(heroSchemaLiteral);\n\n// aggregate the document type from the schema\nexport type HeroDocType = ExtractDocumentTypeFromTypedRxJsonSchema;\n\n// create the typed RxJsonSchema from the literal typed object.\nexport const heroSchema: RxJsonSchema = heroSchemaLiteral;\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Option B"}),": Manually type the document type"]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocType = {\n passportId: string;\n firstName: string;\n lastName: string;\n age?: number; // optional\n};\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Option C"}),": Generate the document type from schema during build time"]}),(0,o.jsxs)(t.p,{children:["If your schema is in a ",(0,o.jsx)(t.code,{children:".json"})," file or generated from somewhere else, you might generate the typings with the ",(0,o.jsx)(t.a,{href:"https://www.npmjs.com/package/json-schema-to-typescript",children:"json-schema-to-typescript"})," module."]}),(0,o.jsx)(t.h2,{id:"types-for-the-orm-methods",children:"Types for the ORM methods"}),(0,o.jsx)(t.p,{children:"We also add some ORM-methods for the document."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocMethods = {\n scream: (v: string) => string;\n};\n"})}),(0,o.jsx)(t.h2,{id:"create-rxdocument-type",children:"Create RxDocument Type"}),(0,o.jsx)(t.p,{children:"We can merge these into our HeroDocument."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocument = RxDocument;\n"})}),(0,o.jsx)(t.h2,{id:"create-rxcollection-type",children:"Create RxCollection Type"}),(0,o.jsx)(t.p,{children:"Now we can define type for the collection which contains the documents."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"\n// we declare one static ORM-method for the collection\nexport type HeroCollectionMethods = {\n countAllDocuments: () => Promise;\n}\n\n// and then merge all our types\nexport type HeroCollection = RxCollection<\n HeroDocType,\n HeroDocMethods,\n HeroCollectionMethods\n>;\n"})}),(0,o.jsx)(t.h2,{id:"create-rxdatabase-type",children:"Create RxDatabase Type"}),(0,o.jsx)(t.p,{children:"Before we can define the database, we make a helper-type which contains all collections of it."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"export type MyDatabaseCollections = {\n heroes: HeroCollection\n}\n"})}),(0,o.jsx)(t.p,{children:"Now the database."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"export type MyDatabase = RxDatabase;\n"})})]}),"\n",(0,o.jsx)(t.h2,{id:"using-the-types",children:"Using the types"}),"\n",(0,o.jsx)(t.p,{children:"Now that we have declare all our types, we can use them."}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-typescript",children:"\n/**\n * create database and collections\n */\nconst myDatabase: MyDatabase = await createRxDatabase({\n name: 'mydb',\n storage: getRxStorageDexie()\n});\n\nconst heroSchema: RxJsonSchema = {\n title: 'human schema',\n description: 'describes a human being',\n version: 0,\n keyCompression: true,\n primaryKey: 'passportId',\n type: 'object',\n properties: {\n passportId: {\n type: 'string'\n },\n firstName: {\n type: 'string'\n },\n lastName: {\n type: 'string'\n },\n age: {\n type: 'integer'\n }\n },\n required: ['passportId', 'firstName', 'lastName']\n};\n\nconst heroDocMethods: HeroDocMethods = {\n scream: function(this: HeroDocument, what: string) {\n return this.firstName + ' screams: ' + what.toUpperCase();\n }\n};\n\nconst heroCollectionMethods: HeroCollectionMethods = {\n countAllDocuments: async function(this: HeroCollection) {\n const allDocs = await this.find().exec();\n return allDocs.length;\n }\n};\n\nawait myDatabase.addCollections({\n heroes: {\n schema: heroSchema,\n methods: heroDocMethods,\n statics: heroCollectionMethods\n }\n});\n\n// add a postInsert-hook\nmyDatabase.heroes.postInsert(\n function myPostInsertHook(\n this: HeroCollection, // own collection is bound to the scope\n docData: HeroDocType, // documents data\n doc: HeroDocument // RxDocument\n ) {\n console.log('insert to ' + this.name + '-collection: ' + doc.firstName);\n },\n false // not async\n);\n\n/**\n * use the database\n */\n\n// insert a document\nconst hero: HeroDocument = await myDatabase.heroes.insert({\n passportId: 'myId',\n firstName: 'piotr',\n lastName: 'potter',\n age: 5\n});\n\n// access a property\nconsole.log(hero.firstName);\n\n// use a orm method\nhero.scream('AAH!');\n\n// use a static orm method from the collection\nconst amount: number = await myDatabase.heroes.countAllDocuments();\nconsole.log(amount);\n\n\n/**\n * clean up\n */\nmyDatabase.close();\n"})}),"\n",(0,o.jsx)(t.h2,{id:"known-problems",children:"Known Problems"}),"\n",(0,o.jsxs)(t.p,{children:["RxDB uses the ",(0,o.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef",children:"WeakRef API"}),". If your typescript bundler throws the error ",(0,o.jsx)(t.code,{children:"TS2304: Cannot find name 'WeakRef'"}),", you have to add ",(0,o.jsx)(t.code,{children:"ES2021.WeakRef"})," to ",(0,o.jsx)(t.code,{children:"compilerOptions.lib"})," in your ",(0,o.jsx)(t.code,{children:"tsconfig.json"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-json",children:'{\n "compilerOptions": {\n "lib": ["ES2020", "ES2021.WeakRef"]\n }\n}\n'})})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},7580:(e,t,n)=>{n.d(t,{g:()=>o});var s=n(4848);function o(e){const t=[];let n=null;return e.children.forEach((e=>{e.props.id?(n&&t.push(n),n={headline:e,paragraphs:[]}):n&&n.paragraphs.push(e)})),n&&t.push(n),(0,s.jsx)("div",{style:r.stepsContainer,children:t.map(((e,t)=>(0,s.jsxs)("div",{style:r.stepWrapper,children:[(0,s.jsxs)("div",{style:r.stepIndicator,children:[(0,s.jsxs)("div",{style:r.stepNumber,children:[t+1,"."]}),(0,s.jsx)("div",{style:r.verticalLine})]}),(0,s.jsxs)("div",{style:r.stepContent,children:[(0,s.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,t)=>(0,s.jsx)("div",{style:r.item,children:e},t)))]})]},t)))})}const r={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(6540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2efd0200.65245364.js b/docs/assets/js/2efd0200.65245364.js deleted file mode 100644 index 35c1234c5b9..00000000000 --- a/docs/assets/js/2efd0200.65245364.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4132],{1780:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"tutorials/typescript","title":"TypeScript Setup","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide.","source":"@site/docs/tutorials/typescript.md","sourceDirName":"tutorials","slug":"/tutorials/typescript.html","permalink":"/tutorials/typescript.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"TypeScript Setup","slug":"typescript.html","description":"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide."},"sidebar":"tutorialSidebar","previous":{"title":"Development Mode","permalink":"/dev-mode.html"},"next":{"title":"RxDatabase","permalink":"/rx-database.html"}}');var s=n(4848),r=n(8453);const a={title:"TypeScript Setup",slug:"typescript.html",description:"Use RxDB with TypeScript to define typed schemas, create typed collections, and build fully typed ORM methods. A quick step-by-step guide."},c="Using RxDB with TypeScript",i={},l=[{value:"Declare the types",id:"declare-the-types",level:2},{value:"Create the base document type",id:"create-the-base-document-type",level:2},{value:"Option A: Create the document type from the schema",id:"option-a-create-the-document-type-from-the-schema",level:3},{value:"Option B: Manually type the document type",id:"option-b-manually-type-the-document-type",level:3},{value:"Option C: Generate the document type from schema during build time",id:"option-c-generate-the-document-type-from-schema-during-build-time",level:3},{value:"Types for the ORM methods",id:"types-for-the-orm-methods",level:2},{value:"Using the types",id:"using-the-types",level:2},{value:"Known Problems",id:"known-problems",level:2}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"using-rxdb-with-typescript",children:"Using RxDB with TypeScript"})}),"\n",(0,s.jsx)(t.p,{children:"In this tutorial you will learn how to use RxDB with TypeScript.\nWe will create a basic database with one collection and several ORM-methods, fully typed!"}),"\n",(0,s.jsx)(t.p,{children:"RxDB directly comes with its typings and you do not have to install anything else, however the latest version of RxDB requires that you are using Typescript v3.8 or newer.\nOur way to go is"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"First define what the documents look like"}),"\n",(0,s.jsx)(t.li,{children:"Then define what the collections look like"}),"\n",(0,s.jsx)(t.li,{children:"Then define what the database looks like"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"declare-the-types",children:"Declare the types"}),"\n",(0,s.jsx)(t.p,{children:"First you import the types from RxDB."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"import {\n createRxDatabase,\n RxDatabase,\n RxCollection,\n RxJsonSchema,\n RxDocument,\n} from 'rxdb';\n"})}),"\n",(0,s.jsx)(t.h2,{id:"create-the-base-document-type",children:"Create the base document type"}),"\n",(0,s.jsx)(t.p,{children:"First we have to define the TypeScript type of the documents of a collection:"}),"\n",(0,s.jsx)(t.h3,{id:"option-a-create-the-document-type-from-the-schema",children:"Option A: Create the document type from the schema"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"import {\n toTypedRxJsonSchema,\n ExtractDocumentTypeFromTypedRxJsonSchema,\n RxJsonSchema\n} from 'rxdb';\nexport const heroSchemaLiteral = {\n title: 'hero schema',\n description: 'describes a human being',\n version: 0,\n keyCompression: true,\n primaryKey: 'passportId',\n type: 'object',\n properties: {\n passportId: {\n type: 'string',\n maxLength: 100 // <- the primary key must have set maxLength\n },\n firstName: {\n type: 'string'\n },\n lastName: {\n type: 'string'\n },\n age: {\n type: 'integer'\n }\n },\n required: ['firstName', 'lastName', 'passportId'],\n indexes: ['firstName']\n} as const; // <- It is important to set 'as const' to preserve the literal type\nconst schemaTyped = toTypedRxJsonSchema(heroSchemaLiteral);\n\n// aggregate the document type from the schema\nexport type HeroDocType = ExtractDocumentTypeFromTypedRxJsonSchema;\n\n// create the typed RxJsonSchema from the literal typed object.\nexport const heroSchema: RxJsonSchema = heroSchemaLiteral;\n"})}),"\n",(0,s.jsx)(t.h3,{id:"option-b-manually-type-the-document-type",children:"Option B: Manually type the document type"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocType = {\n passportId: string;\n firstName: string;\n lastName: string;\n age?: number; // optional\n};\n"})}),"\n",(0,s.jsx)(t.h3,{id:"option-c-generate-the-document-type-from-schema-during-build-time",children:"Option C: Generate the document type from schema during build time"}),"\n",(0,s.jsxs)(t.p,{children:["If your schema is in a ",(0,s.jsx)(t.code,{children:".json"})," file or generated from somewhere else, you might generate the typings with the ",(0,s.jsx)(t.a,{href:"https://www.npmjs.com/package/json-schema-to-typescript",children:"json-schema-to-typescript"})," module."]}),"\n",(0,s.jsx)(t.h2,{id:"types-for-the-orm-methods",children:"Types for the ORM methods"}),"\n",(0,s.jsx)(t.p,{children:"We also add some ORM-methods for the document."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocMethods = {\n scream: (v: string) => string;\n};\n"})}),"\n",(0,s.jsx)(t.p,{children:"We can merge these into our HeroDocument."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"export type HeroDocument = RxDocument;\n"})}),"\n",(0,s.jsx)(t.p,{children:"Now we can define type for the collection which contains the documents."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"\n// we declare one static ORM-method for the collection\nexport type HeroCollectionMethods = {\n countAllDocuments: () => Promise;\n}\n\n// and then merge all our types\nexport type HeroCollection = RxCollection;\n"})}),"\n",(0,s.jsx)(t.p,{children:"Before we can define the database, we make a helper-type which contains all collections of it."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"export type MyDatabaseCollections = {\n heroes: HeroCollection\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"Now the database."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"export type MyDatabase = RxDatabase;\n"})}),"\n",(0,s.jsx)(t.h2,{id:"using-the-types",children:"Using the types"}),"\n",(0,s.jsx)(t.p,{children:"Now that we have declare all our types, we can use them."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-typescript",children:"\n/**\n * create database and collections\n */\nconst myDatabase: MyDatabase = await createRxDatabase({\n name: 'mydb',\n storage: getRxStorageDexie()\n});\n\nconst heroSchema: RxJsonSchema = {\n title: 'human schema',\n description: 'describes a human being',\n version: 0,\n keyCompression: true,\n primaryKey: 'passportId',\n type: 'object',\n properties: {\n passportId: {\n type: 'string'\n },\n firstName: {\n type: 'string'\n },\n lastName: {\n type: 'string'\n },\n age: {\n type: 'integer'\n }\n },\n required: ['passportId', 'firstName', 'lastName']\n};\n\nconst heroDocMethods: HeroDocMethods = {\n scream: function(this: HeroDocument, what: string) {\n return this.firstName + ' screams: ' + what.toUpperCase();\n }\n};\n\nconst heroCollectionMethods: HeroCollectionMethods = {\n countAllDocuments: async function(this: HeroCollection) {\n const allDocs = await this.find().exec();\n return allDocs.length;\n }\n};\n\nawait myDatabase.addCollections({\n heroes: {\n schema: heroSchema,\n methods: heroDocMethods,\n statics: heroCollectionMethods\n }\n});\n\n// add a postInsert-hook\nmyDatabase.heroes.postInsert(\n function myPostInsertHook(\n this: HeroCollection, // own collection is bound to the scope\n docData: HeroDocType, // documents data\n doc: HeroDocument // RxDocument\n ) {\n console.log('insert to ' + this.name + '-collection: ' + doc.firstName);\n },\n false // not async\n);\n\n/**\n * use the database\n */\n\n// insert a document\nconst hero: HeroDocument = await myDatabase.heroes.insert({\n passportId: 'myId',\n firstName: 'piotr',\n lastName: 'potter',\n age: 5\n});\n\n// access a property\nconsole.log(hero.firstName);\n\n// use a orm method\nhero.scream('AAH!');\n\n// use a static orm method from the collection\nconst amount: number = await myDatabase.heroes.countAllDocuments();\nconsole.log(amount);\n\n\n/**\n * clean up\n */\nmyDatabase.close();\n"})}),"\n",(0,s.jsx)(t.h2,{id:"known-problems",children:"Known Problems"}),"\n",(0,s.jsxs)(t.p,{children:["RxDB uses the ",(0,s.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef",children:"WeakRef API"}),". If your typescript bundler throws the error ",(0,s.jsx)(t.code,{children:"TS2304: Cannot find name 'WeakRef'"}),", you have to add ",(0,s.jsx)(t.code,{children:"ES2021.WeakRef"})," to ",(0,s.jsx)(t.code,{children:"compilerOptions.lib"})," in your ",(0,s.jsx)(t.code,{children:"tsconfig.json"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'{\n "compilerOptions": {\n "lib": ["ES2020", "ES2021.WeakRef"]\n }\n}\n'})})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var o=n(6540);const s={},r=o.createContext(s);function a(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/326aca46.d9f5bc57.js b/docs/assets/js/326aca46.4784df5e.js similarity index 50% rename from docs/assets/js/326aca46.d9f5bc57.js rename to docs/assets/js/326aca46.4784df5e.js index 00b305d8296..b35e2e0a741 100644 --- a/docs/assets/js/326aca46.d9f5bc57.js +++ b/docs/assets/js/326aca46.4784df5e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4853],{2965:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});const a=JSON.parse('{"id":"offline-first","title":"Local First / Offline First","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency.","source":"@site/docs/offline-first.md","sourceDirName":".","slug":"/offline-first.html","permalink":"/offline-first.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Local First / Offline First","slug":"offline-first.html","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency."},"sidebar":"tutorialSidebar","previous":{"title":"8.0.0","permalink":"/releases/8.0.0.html"},"next":{"title":"Downsides of Local First / Offline First","permalink":"/downsides-of-offline-first.html"}}');var i=n(4848),s=n(8453);const o={title:"Local First / Offline First",slug:"offline-first.html",description:"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency."},r="Local First / Offline First",l={},h=[{value:"UX is better without loading spinners",id:"ux-is-better-without-loading-spinners",level:2},{value:"Multi-tab usage just works",id:"multi-tab-usage-just-works",level:2},{value:"Latency is more important than bandwidth",id:"latency-is-more-important-than-bandwidth",level:2},{value:"Realtime comes for free",id:"realtime-comes-for-free",level:2},{value:"Scales with data size, not with the amount of user interaction",id:"scales-with-data-size-not-with-the-amount-of-user-interaction",level:2},{value:"Modern apps have longer runtimes",id:"modern-apps-have-longer-runtimes",level:2},{value:"You might not need REST",id:"you-might-not-need-rest",level:2},{value:"You might not need Redux",id:"you-might-not-need-redux",level:2},{value:"Follow up",id:"follow-up",level:2}];function c(e){const t={a:"a",blockquote:"blockquote",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"local-first--offline-first",children:"Local First / Offline First"})}),"\n",(0,i.jsxs)(t.p,{children:["Local-First (aka offline first) is a software paradigm where the software stores data locally at the clients device and must work as well offline as it does online.\nTo implement this, you have to store data at the client side, so that your application can still access it when the internet goes away.\nThis can be either done with complex caching strategies, or by using an local-first, ",(0,i.jsx)(t.a,{href:"/articles/offline-database.html",children:"offline database"})," (like ",(0,i.jsx)(t.a,{href:"https://rxdb.info",children:"RxDB"}),") that stores the data inside of a local database like ",(0,i.jsx)(t.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB"})," and replicates it from and to the backend in the background. This makes the local database, not the server, the gateway for all persistent changes in application state."]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Offline first is not about having no internet connection"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"While in the past, internet connection was an unstable, things are changing especially for mobile devices.\nMobile networks become better and having no internet becomes less common even in remote locations.\nSo if we did not care about offline first applications in the past, why should we even care now?\nIn the following I will point out why offline first applications are better, not because they support offline usage, but because of other reasons."}),"\n",(0,i.jsx)("center",{children:(0,i.jsx)("a",{href:"https://rxdb.info/",children:(0,i.jsx)("img",{src:"../files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"220"})})}),"\n",(0,i.jsx)(t.h2,{id:"ux-is-better-without-loading-spinners",children:"UX is better without loading spinners"}),"\n",(0,i.jsx)(t.p,{children:"In 'normal' web applications, most user interactions like fetching, saving or deleting data, correspond to a request to the backend server. This means that each of these interactions require the user to await the unknown latency to and from a remote server while looking at a loading spinner.\nIn offline-first apps, the operations go directly against the local storage which happens almost instantly. There is no perceptible loading time and so it is not even necessary to implement a loading spinner at all. As soon as the user clicks, the UI represents the new state as if it was already changed in the backend."}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/loading-spinner-not-needed.gif",alt:"loading spinner not needed",width:"300"})}),"\n",(0,i.jsx)(t.h2,{id:"multi-tab-usage-just-works",children:"Multi-tab usage just works"}),"\n",(0,i.jsxs)(t.p,{children:["Many, even big websites like amazon, reddit and stack overflow do not handle multi tab usage correctly. When a user has multiple tabs of the website open and does a login on one of these tabs, the state does not change on the other tabs.\nOn offline first applications, there is always exactly one state of the data across all tabs. Offline first databases (like RxDB) store the data inside of IndexedDb and ",(0,i.jsx)(t.strong,{children:"share the state"})," between all tabs of the same origin."]}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/multiwindow.gif",alt:"RxDB multi tab",width:"450"})}),"\n",(0,i.jsx)(t.h2,{id:"latency-is-more-important-than-bandwidth",children:"Latency is more important than bandwidth"}),"\n",(0,i.jsx)(t.p,{children:"In the past, often the bandwidth was the limiting factor on determining the loading time of an application.\nBut while bandwidth has improved over the years, latency became the limiting factor.\nYou can always increase the bandwidth by setting up more cables or sending more Starlink satellites to space.\nBut reducing the latency is not so easy. It is defined by the physical properties of the transfer medium, the speed of light and the distance to the server. All of these three are hard to optimize."}),"\n",(0,i.jsx)(t.p,{children:"Offline first application benefit from that because sending the initial state to the client can be done much faster with more bandwidth. And once the data is there, we do no longer have to care about the latency to the backend server."}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/latency-london-san-franzisco.png",alt:"latency london san franzisco",width:"300"})}),"\n",(0,i.jsx)(t.h2,{id:"realtime-comes-for-free",children:"Realtime comes for free"}),"\n",(0,i.jsxs)(t.p,{children:["Most websites lie to their users. They do not lie because they display wrong data, but because they display ",(0,i.jsx)(t.strong,{children:"old data"})," that was loaded from the backend at the time the user opened the site.\nTo overcome this, you could build a realtime website where you create a websocket that streams updates from the backend to the client. This means work. Your client needs to tell the server which page is currently opened and which updates the client is interested to. Then the server can push updates over the websocket and you can update the UI accordingly."]}),"\n",(0,i.jsxs)(t.p,{children:["With offline first applications, you already have a realtime replication with the backend. Most offline first databases provide some concept of changestream or data subscriptions and with ",(0,i.jsx)(t.a,{href:"https://github.com/pubkey/rxdb",children:"RxDB"})," you can even directly subscribe to query results or single fields of documents. This makes it easy to have an always updated UI whenever data on the backend changes."]}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/animations/realtime.gif",alt:"realtime ui updates",width:"700"})}),"\n",(0,i.jsx)(t.h2,{id:"scales-with-data-size-not-with-the-amount-of-user-interaction",children:"Scales with data size, not with the amount of user interaction"}),"\n",(0,i.jsx)(t.p,{children:"On normal applications, each user interaction can result in multiple requests to the backend server which increase its load.\nThe more users interact with your application, the more backend resources you have to provide."}),"\n",(0,i.jsx)(t.p,{children:"Offline first applications do not scale up with the amount of user actions but instead they scale up with the amount of data.\nOnce that data is transferred to the client, the user can do as many interactions with it as required without connecting to the server."}),"\n",(0,i.jsx)(t.h2,{id:"modern-apps-have-longer-runtimes",children:"Modern apps have longer runtimes"}),"\n",(0,i.jsx)(t.p,{children:"In the past you used websites only for a short time. You open it, perform some action and then close it again. This made the first load time the important metric when evaluating page speed.\nToday web applications have changed and with it the way we use them. Single page applications are opened once and then used over the whole day. Chat apps, email clients, PWAs and hybrid apps. All of these were made to have long runtimes.\nThis makes the time for user interactions more important than the initial loading time. Offline first applications benefit from that because there is often no loading time on user actions while loading the initial state to the client is not that relevant."}),"\n",(0,i.jsx)(t.h2,{id:"you-might-not-need-rest",children:"You might not need REST"}),"\n",(0,i.jsx)(t.p,{children:"On normal web applications, you make different requests for each kind of data interaction.\nFor that you have to define a swagger route, implement a route handler on the backend and create some client code to send or fetch data from that route. The more complex your application becomes, the more REST routes you have to maintain and implement."}),"\n",(0,i.jsxs)(t.p,{children:["With offline first apps, you have a way to hack around all this cumbersome work. You just replicate the whole state from the server to the client. The replication does not only run once, you have a ",(0,i.jsx)(t.strong,{children:"realtime replication"})," and all changes at one side are automatically there on the other side. On the client, you can access every piece of state with a simple database query.\nWhile this of course only works for amounts of data that the client can load and store, it makes implementing prototypes and simple apps much faster."]}),"\n",(0,i.jsx)(t.h2,{id:"you-might-not-need-redux",children:"You might not need Redux"}),"\n",(0,i.jsx)(t.p,{children:"Data is hard, especially for UI applications where many things can happen at the same time.\nThe user is clicking around. Stuff is loaded from the server. All of these things interact with the global state of the app.\nTo manage this complexity it is common to use state management libraries like Redux or MobX. With them, you write all this lasagna code to wrap the mutation of data and to make the UI react to all these changes."}),"\n",(0,i.jsx)(t.p,{children:"On offline first apps, your global state is already there in a single place stored inside of the local database.\nYou do not have to care whether this data came from the UI, another tab, the backend or another device of the same user. You can just make writes to the database and fetch data out of it."}),"\n",(0,i.jsx)(t.h2,{id:"follow-up",children:"Follow up"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Learn how to store and query data with RxDB in the ",(0,i.jsx)(t.a,{href:"/quickstart.html",children:"RxDB Quickstart"})]}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/downsides-of-offline-first.html",children:"Downsides of Offline First"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(6540);const i={},s=a.createContext(i);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4853],{2965:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});const a=JSON.parse('{"id":"offline-first","title":"Local First / Offline First","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency.","source":"@site/docs/offline-first.md","sourceDirName":".","slug":"/offline-first.html","permalink":"/offline-first.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Local First / Offline First","slug":"offline-first.html","description":"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency."},"sidebar":"tutorialSidebar","previous":{"title":"8.0.0","permalink":"/releases/8.0.0.html"},"next":{"title":"Downsides of Local First / Offline First","permalink":"/downsides-of-offline-first.html"}}');var i=n(4848),s=n(8453);const o={title:"Local First / Offline First",slug:"offline-first.html",description:"Local-First software stores data on client devices for seamless offline and online functionality, enhancing user experience and efficiency."},r="Local First / Offline First",l={},h=[{value:"UX is better without loading spinners",id:"ux-is-better-without-loading-spinners",level:2},{value:"Multi-tab usage just works",id:"multi-tab-usage-just-works",level:2},{value:"Latency is more important than bandwidth",id:"latency-is-more-important-than-bandwidth",level:2},{value:"Realtime comes for free",id:"realtime-comes-for-free",level:2},{value:"Scales with data size, not with the amount of user interaction",id:"scales-with-data-size-not-with-the-amount-of-user-interaction",level:2},{value:"Modern apps have longer runtimes",id:"modern-apps-have-longer-runtimes",level:2},{value:"You might not need REST",id:"you-might-not-need-rest",level:2},{value:"You might not need Redux",id:"you-might-not-need-redux",level:2},{value:"Follow up",id:"follow-up",level:2}];function c(e){const t={a:"a",blockquote:"blockquote",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"local-first--offline-first",children:"Local First / Offline First"})}),"\n",(0,i.jsxs)(t.p,{children:["Local-First (aka offline first) is a software paradigm where the software stores data locally at the clients device and must work as well offline as it does online.\nTo implement this, you have to store data at the client side, so that your application can still access it when the internet goes away.\nThis can be either done with complex caching strategies, or by using an local-first, ",(0,i.jsx)(t.a,{href:"/articles/offline-database.html",children:"offline database"})," (like ",(0,i.jsx)(t.a,{href:"https://rxdb.info",children:"RxDB"}),") that stores the data inside of a local database like ",(0,i.jsx)(t.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB"})," and replicates it from and to the backend in the background. This makes the local database, not the server, the gateway for all persistent changes in application state."]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Offline first is not about having no internet connection"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"While in the past, internet connection was an unstable, things are changing especially for mobile devices.\nMobile networks become better and having no internet becomes less common even in remote locations.\nSo if we did not care about offline first applications in the past, why should we even care now?\nIn the following I will point out why offline first applications are better, not because they support offline usage, but because of other reasons."}),"\n",(0,i.jsx)("center",{children:(0,i.jsx)("a",{href:"https://rxdb.info/",children:(0,i.jsx)("img",{src:"../files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"220"})})}),"\n",(0,i.jsx)(t.h2,{id:"ux-is-better-without-loading-spinners",children:"UX is better without loading spinners"}),"\n",(0,i.jsx)(t.p,{children:"In 'normal' web applications, most user interactions like fetching, saving or deleting data, correspond to a request to the backend server. This means that each of these interactions require the user to await the unknown latency to and from a remote server while looking at a loading spinner.\nIn offline-first apps, the operations go directly against the local storage which happens almost instantly. There is no perceptible loading time and so it is not even necessary to implement a loading spinner at all. As soon as the user clicks, the UI represents the new state as if it was already changed in the backend."}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/loading-spinner-not-needed.gif",alt:"loading spinner not needed",width:"300"})}),"\n",(0,i.jsx)(t.h2,{id:"multi-tab-usage-just-works",children:"Multi-tab usage just works"}),"\n",(0,i.jsxs)(t.p,{children:["Many, even big websites like amazon, reddit and stack overflow do not handle multi tab usage correctly. When a user has multiple tabs of the website open and does a login on one of these tabs, the state does not change on the other tabs.\nOn offline first applications, there is always exactly one state of the data across all tabs. Offline first databases (like RxDB) store the data inside of IndexedDb and ",(0,i.jsx)(t.strong,{children:"share the state"})," between all tabs of the same origin."]}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/multiwindow.gif",alt:"RxDB multi tab",width:"450"})}),"\n",(0,i.jsx)(t.h2,{id:"latency-is-more-important-than-bandwidth",children:"Latency is more important than bandwidth"}),"\n",(0,i.jsx)(t.p,{children:"In the past, often the bandwidth was the limiting factor on determining the loading time of an application.\nBut while bandwidth has improved over the years, latency became the limiting factor.\nYou can always increase the bandwidth by setting up more cables or sending more Starlink satellites to space.\nBut reducing the latency is not so easy. It is defined by the physical properties of the transfer medium, the speed of light and the distance to the server. All of these three are hard to optimize."}),"\n",(0,i.jsxs)(t.p,{children:["Offline first application benefit from that because sending the initial state to the client can be done much faster with more bandwidth. And once the data is there, we do no longer have to care about the latency to the backend server because you can run near ",(0,i.jsx)(t.a,{href:"/articles/zero-latency-local-first.html",children:"zero"})," latency queries locally."]}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/latency-london-san-franzisco.png",alt:"latency london san franzisco",width:"300"})}),"\n",(0,i.jsx)(t.h2,{id:"realtime-comes-for-free",children:"Realtime comes for free"}),"\n",(0,i.jsxs)(t.p,{children:["Most websites lie to their users. They do not lie because they display wrong data, but because they display ",(0,i.jsx)(t.strong,{children:"old data"})," that was loaded from the backend at the time the user opened the site.\nTo overcome this, you could build a realtime website where you create a websocket that streams updates from the backend to the client. This means work. Your client needs to tell the server which page is currently opened and which updates the client is interested to. Then the server can push updates over the websocket and you can update the UI accordingly."]}),"\n",(0,i.jsxs)(t.p,{children:["With offline first applications, you already have a realtime replication with the backend. Most offline first databases provide some concept of changestream or data subscriptions and with ",(0,i.jsx)(t.a,{href:"https://github.com/pubkey/rxdb",children:"RxDB"})," you can even directly subscribe to query results or single fields of documents. This makes it easy to have an always updated UI whenever data on the backend changes."]}),"\n",(0,i.jsx)("p",{align:"center",children:(0,i.jsx)("img",{src:"./files/animations/realtime.gif",alt:"realtime ui updates",width:"700"})}),"\n",(0,i.jsx)(t.h2,{id:"scales-with-data-size-not-with-the-amount-of-user-interaction",children:"Scales with data size, not with the amount of user interaction"}),"\n",(0,i.jsx)(t.p,{children:"On normal applications, each user interaction can result in multiple requests to the backend server which increase its load.\nThe more users interact with your application, the more backend resources you have to provide."}),"\n",(0,i.jsx)(t.p,{children:"Offline first applications do not scale up with the amount of user actions but instead they scale up with the amount of data.\nOnce that data is transferred to the client, the user can do as many interactions with it as required without connecting to the server."}),"\n",(0,i.jsx)(t.h2,{id:"modern-apps-have-longer-runtimes",children:"Modern apps have longer runtimes"}),"\n",(0,i.jsx)(t.p,{children:"In the past you used websites only for a short time. You open it, perform some action and then close it again. This made the first load time the important metric when evaluating page speed.\nToday web applications have changed and with it the way we use them. Single page applications are opened once and then used over the whole day. Chat apps, email clients, PWAs and hybrid apps. All of these were made to have long runtimes.\nThis makes the time for user interactions more important than the initial loading time. Offline first applications benefit from that because there is often no loading time on user actions while loading the initial state to the client is not that relevant."}),"\n",(0,i.jsx)(t.h2,{id:"you-might-not-need-rest",children:"You might not need REST"}),"\n",(0,i.jsx)(t.p,{children:"On normal web applications, you make different requests for each kind of data interaction.\nFor that you have to define a swagger route, implement a route handler on the backend and create some client code to send or fetch data from that route. The more complex your application becomes, the more REST routes you have to maintain and implement."}),"\n",(0,i.jsxs)(t.p,{children:["With offline first apps, you have a way to hack around all this cumbersome work. You just replicate the whole state from the server to the client. The replication does not only run once, you have a ",(0,i.jsx)(t.strong,{children:"realtime replication"})," and all changes at one side are automatically there on the other side. On the client, you can access every piece of state with a simple database query.\nWhile this of course only works for amounts of data that the client can load and store, it makes implementing prototypes and simple apps much faster."]}),"\n",(0,i.jsx)(t.h2,{id:"you-might-not-need-redux",children:"You might not need Redux"}),"\n",(0,i.jsx)(t.p,{children:"Data is hard, especially for UI applications where many things can happen at the same time.\nThe user is clicking around. Stuff is loaded from the server. All of these things interact with the global state of the app.\nTo manage this complexity it is common to use state management libraries like Redux or MobX. With them, you write all this lasagna code to wrap the mutation of data and to make the UI react to all these changes."}),"\n",(0,i.jsx)(t.p,{children:"On offline first apps, your global state is already there in a single place stored inside of the local database.\nYou do not have to care whether this data came from the UI, another tab, the backend or another device of the same user. You can just make writes to the database and fetch data out of it."}),"\n",(0,i.jsx)(t.h2,{id:"follow-up",children:"Follow up"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Learn how to store and query data with RxDB in the ",(0,i.jsx)(t.a,{href:"/quickstart.html",children:"RxDB Quickstart"})]}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/downsides-of-offline-first.html",children:"Downsides of Offline First"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(6540);const i={},s=a.createContext(i);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/3304.55637374.js b/docs/assets/js/3304.55637374.js deleted file mode 100644 index f8597705f5b..00000000000 --- a/docs/assets/js/3304.55637374.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[3304],{1990:(e,t,r)=>{r.d(t,{Ks:()=>n,V0:()=>a});var a=async function(e){var t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.prototype.map.call(new Uint8Array(r),(e=>("00"+e.toString(16)).slice(-2))).join("")};function n(e){for(var t=0,r=e.length,a=0;a{r.r(t),r.d(t,{getDatabase:()=>na,hasIndexedDB:()=>aa});var a=r(7329);function n(e,t){var r=e.get(t);if(void 0===r)throw new Error("missing value from map "+t);return r}function i(e,t,r,a){var n=e.get(t);return void 0===n?(n=r(),e.set(t,n)):a&&a(n),n}function s(e){return Object.assign({},e)}function o(e,t){if(void 0===t&&(t=!1),!e)return e;if(!t&&Array.isArray(e))return e.sort(((e,t)=>"string"==typeof e&&"string"==typeof t?e.localeCompare(t):"object"==typeof e?1:-1)).map((e=>o(e,t)));if("object"==typeof e&&!Array.isArray(e)){var r={};return Object.keys(e).sort(((e,t)=>e.localeCompare(t))).forEach((a=>{r[a]=o(e[a],t)})),r}return e}var c=function e(t){if(!t)return t;if(null===t||"object"!=typeof t)return t;if(Array.isArray(t)){for(var r=new Array(t.length),a=r.length;a--;)r[a]=e(t[a]);return r}var n={};for(var i in t)n[i]=e(t[i]);return n};function u(e,t,r){return Object.defineProperty(e,t,{get:function(){return r}}),r}var h=e=>{var t=typeof e;return null!==e&&("object"===t||"function"===t)},l=new Set(["__proto__","prototype","constructor"]),d=new Set("0123456789");function m(e){var t=[],r="",a="start",n=!1;for(var i of e)switch(i){case"\\":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a)throw new Error("Invalid character after an index");n&&(r+=i),a="property",n=!n;break;case".":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a){a="property";break}if(n){n=!1,r+=i;break}if(l.has(r))return[];t.push(r),r="",a="property";break;case"[":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a){a="index";break}if(n){n=!1,r+=i;break}if("property"===a){if(l.has(r))return[];t.push(r),r=""}a="index";break;case"]":if("index"===a){t.push(Number.parseInt(r,10)),r="",a="indexEnd";break}if("indexEnd"===a)throw new Error("Invalid character after an index");default:if("index"===a&&!d.has(i))throw new Error("Invalid character in an index");if("indexEnd"===a)throw new Error("Invalid character after an index");"start"===a&&(a="property"),n&&(n=!1,r+="\\"),r+=i}switch(n&&(r+="\\"),a){case"property":if(l.has(r))return[];t.push(r);break;case"index":throw new Error("Index was not closed");case"start":t.push("")}return t}function f(e,t){if("number"!=typeof t&&Array.isArray(e)){var r=Number.parseInt(t,10);return Number.isInteger(r)&&e[r]===e[t]}return!1}function p(e,t){if(f(e,t))throw new Error("Cannot use string index")}function v(e,t,r){if(Array.isArray(t)&&(t=t.join(".")),!t.includes(".")&&!t.includes("["))return e[t];if(!h(e)||"string"!=typeof t)return void 0===r?e:r;var a=m(t);if(0===a.length)return r;for(var n=0;n!1,deepFreezeWhenDevMode:e=>e,tunnelErrorMessage:e=>"\n RxDB Error-Code: "+e+".\n Hint: Error messages are not included in RxDB core to reduce build size.\n To show the full error messages and to ensure that you do not make any mistakes when using RxDB,\n use the dev-mode plugin when you are in development mode: https://rxdb.info/dev-mode.html?console=error\n "};function E(e,t,r){return"\n"+e+"\n"+function(e){var t="";return 0===Object.keys(e).length?t:(t+="-".repeat(20)+"\n",t+="Parameters:\n",t+=Object.keys(e).map((t=>{var r="[object Object]";try{r="errors"===t?e[t].map((e=>JSON.stringify(e,Object.getOwnPropertyNames(e)))):JSON.stringify(e[t],(function(e,t){return void 0===t?null:t}),2)}catch(a){}return t+": "+r})).join("\n"),t+="\n")}(r)}var R=function(e){function t(t,r,a){var n;void 0===a&&(a={});var i=E(r,0,a);return(n=e.call(this,i)||this).code=t,n.message=i,n.url=O(t),n.parameters=a,n.rxdb=!0,n}return(0,k.A)(t,e),t.prototype.toString=function(){return this.message},(0,x.A)(t,[{key:"name",get:function(){return"RxError ("+this.code+")"}},{key:"typeError",get:function(){return!1}}])}((0,_.A)(Error)),C=function(e){function t(t,r,a){var n;void 0===a&&(a={});var i=E(r,0,a);return(n=e.call(this,i)||this).code=t,n.message=i,n.url=O(t),n.parameters=a,n.rxdb=!0,n}return(0,k.A)(t,e),t.prototype.toString=function(){return this.message},(0,x.A)(t,[{key:"name",get:function(){return"RxTypeError ("+this.code+")"}},{key:"typeError",get:function(){return!0}}])}((0,_.A)(TypeError));function O(e){return"https://rxdb.info/errors.html?console=errors#"+e}function P(e){return"\nFind out more about this error here: "+O(e)+" \n"}function S(e,t){return new R(e,I.tunnelErrorMessage(e)+P(e),t)}function j(e,t){return new C(e,I.tunnelErrorMessage(e)+P(e),t)}function $(e){return!(!e||409!==e.status)&&e}var N={409:"document write conflict",422:"schema validation error",510:"attachment data missing"};function A(e){return S("COL20",{name:N[e.status],document:e.documentId,writeError:e})}var B=/\./g,M=r(7587);function q(e,t){var r=t;return r="properties."+(r=r.replace(B,".properties.")),v(e,r=(0,M.L$)(r))}function T(e){return"string"==typeof e?e:e.key}function L(e,t){if("string"==typeof e.primaryKey)return t[e.primaryKey];var r=e.primaryKey;return r.fields.map((e=>{var r=v(t,e);if(void 0===r)throw S("DOC18",{args:{field:e,documentData:t}});return r})).join(r.separator)}function Q(e){var t=T((e=s(e)).primaryKey);e.properties=s(e.properties),e.additionalProperties=!1,Object.prototype.hasOwnProperty.call(e,"keyCompression")||(e.keyCompression=!1),e.indexes=e.indexes?e.indexes.slice(0):[],e.required=e.required?e.required.slice(0):[],e.encrypted=e.encrypted?e.encrypted.slice(0):[],e.properties._rev={type:"string",minLength:1},e.properties._attachments={type:"object"},e.properties._deleted={type:"boolean"},e.properties._meta=F,e.required=e.required?e.required.slice(0):[],e.required.push("_deleted"),e.required.push("_rev"),e.required.push("_meta"),e.required.push("_attachments");var r=W(e);D(e.required,r),e.required=e.required.filter((e=>!e.includes("."))).filter(((e,t,r)=>r.indexOf(e)===t)),e.version=e.version||0;var a=e.indexes.map((e=>{var r=b(e)?e.slice(0):[e];return r.includes(t)||r.push(t),"_deleted"!==r[0]&&r.unshift("_deleted"),r}));0===a.length&&a.push(function(e){return["_deleted",e]}(t)),a.push(["_meta.lwt",t]),e.internalIndexes&&e.internalIndexes.map((e=>{a.push(e)}));var n=new Set;return a.filter((e=>{var t=e.join(",");return!n.has(t)&&(n.add(t),!0)})),e.indexes=a,e}var F={type:"object",properties:{lwt:{type:"number",minimum:1,maximum:1e15,multipleOf:.01}},additionalProperties:!0,required:["lwt"]};function W(e){var t=Object.keys(e.properties).filter((t=>e.properties[t].final)),r=T(e.primaryKey);return t.push(r),"string"!=typeof e.primaryKey&&e.primaryKey.fields.forEach((e=>t.push(e))),t}var H="docs",K="changes",z="attachments",Z="dexie",U=new Map,V=new Map;var J="__";function Y(e){var t=e.split(".");if(t.length>1)return t.map((e=>Y(e))).join(".");if(e.startsWith("|")){var r=e.substring(1);return J+r}return e}function G(e){var t=e.split(".");return t.length>1?t.map((e=>G(e))).join("."):e.startsWith(J)?"|"+e.substring(J.length):e}function X(e,t){if(!t)return t;var r=s(t);return r=te(r),e.forEach((e=>{var a=v(t,e)?"1":"0",n=Y(e);y(r,n,a)})),r}function ee(e,t){return t?(t=re(t=s(t)),e.forEach((e=>{var r=v(t,e);y(t,e,"1"===r)})),t):t}function te(e){if(!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e))return e.map((e=>te(e)));if("object"==typeof e){var t={};return Object.entries(e).forEach((e=>{let[r,a]=e;"object"==typeof a&&(a=te(a)),t[Y(r)]=a})),t}}function re(e){if(!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e))return e.map((e=>re(e)));if("object"==typeof e){var t={};return Object.entries(e).forEach((r=>{let[a,n]=r;("object"==typeof n||Array.isArray(e))&&(n=re(n)),t[G(a)]=n})),t}}function ae(e){var t=[],r=T(e.primaryKey);t.push([r]),t.push(["_deleted",r]),e.indexes&&e.indexes.forEach((e=>{var r=g(e);t.push(r)})),t.push(["_meta.lwt",r]),t.push(["_meta.lwt"]);var a=(t=t.map((e=>e.map((e=>Y(e)))))).map((e=>1===e.length?e[0]:"["+e.join("+")+"]"));return(a=a.filter(((e,t,r)=>r.indexOf(e)===t))).join(", ")}async function ne(e,t){var r=await e;return(await r.dexieTable.bulkGet(t)).map((e=>ee(r.booleanIndexes,e)))}function ie(e,t){return e+"||"+t}function se(e){var t=new Set,r=[];return e.indexes?(e.indexes.forEach((a=>{g(a).forEach((a=>{t.has(a)||(t.add(a),"boolean"===q(e,a).type&&r.push(a))}))})),r.push("_deleted"),r.filter((function(e,t,r){return r.indexOf(e)===t}))):r}var oe=r(9092),ce=0;function ue(){var e=Date.now();(e+=.01)<=ce&&(e=ce+.01);var t=parseFloat(e.toFixed(2));return ce=t,t}var he={},le=r(1990),de=r(8289),me=de.Dr,fe=!1;async function pe(){return fe?me:(fe=!0,me=(async()=>!(!he.premium||"string"!=typeof he.premium||"6da4936d1425ff3a5c44c02342c6daf791d266be3ae8479b8ec59e261df41b93"!==await(0,le.V0)(he.premium)))())}var ve=r(4978),ye=String.fromCharCode(65535),ge=Number.MIN_SAFE_INTEGER;function be(e,t){var r=t.selector,a=e.indexes?e.indexes.slice(0):[];t.index&&(a=[t.index]);var n=!!t.sort.find((e=>"desc"===Object.values(e)[0])),i=new Set;Object.keys(r).forEach((t=>{var a=q(e,t);a&&"boolean"===a.type&&Object.prototype.hasOwnProperty.call(r[t],"$eq")&&i.add(t)}));var s,o=t.sort.map((e=>Object.keys(e)[0])).filter((e=>!i.has(e))).join(","),c=-1;if(a.forEach((e=>{var a=!0,u=!0,h=e.map((e=>{var t=r[e],n=t?Object.keys(t):[],i={};t&&n.length?n.forEach((e=>{if(we.has(e)){var r=function(e,t){switch(e){case"$eq":return{startKey:t,endKey:t,inclusiveEnd:!0,inclusiveStart:!0};case"$lte":return{endKey:t,inclusiveEnd:!0};case"$gte":return{startKey:t,inclusiveStart:!0};case"$lt":return{endKey:t,inclusiveEnd:!1};case"$gt":return{startKey:t,inclusiveStart:!1};default:throw new Error("SNH")}}(e,t[e]);i=Object.assign(i,r)}})):i={startKey:u?ge:ye,endKey:a?ye:ge,inclusiveStart:!0,inclusiveEnd:!0};return void 0===i.startKey&&(i.startKey=ge),void 0===i.endKey&&(i.endKey=ye),void 0===i.inclusiveStart&&(i.inclusiveStart=!0),void 0===i.inclusiveEnd&&(i.inclusiveEnd=!0),u&&!i.inclusiveStart&&(u=!1),a&&!i.inclusiveEnd&&(a=!1),i})),l=h.map((e=>e.startKey)),d=h.map((e=>e.endKey)),m={index:e,startKeys:l,endKeys:d,inclusiveEnd:a,inclusiveStart:u,sortSatisfiedByIndex:!n&&o===e.filter((e=>!i.has(e))).join(","),selectorSatisfiedByIndex:ke(e,t.selector,l,d)},f=function(e,t,r){var a=0,n=e=>{e>0&&(a+=e)},i=10,s=w(r.startKeys,(e=>e!==ge&&e!==ye));n(s*i);var o=w(r.startKeys,(e=>e!==ye&&e!==ge));n(o*i);var c=w(r.startKeys,((e,t)=>e===r.endKeys[t]));n(c*i*1.5);var u=r.sortSatisfiedByIndex?5:0;return n(u),a}(0,0,m);(f>=c||t.index)&&(c=f,s=m)})),!s)throw S("SNH",{query:t});return s}var we=new Set(["$eq","$gt","$gte","$lt","$lte"]),De=new Set(["$eq","$gt","$gte"]),xe=new Set(["$eq","$lt","$lte"]);function ke(e,t,r,a){var n=Object.entries(t).find((t=>{let[r,a]=t;return!e.includes(r)||Object.entries(a).find((e=>{let[t,r]=e;return!we.has(t)}))}));if(n)return!1;if(t.$and||t.$or)return!1;var i=[],s=new Set;for(var[o,c]of Object.entries(t)){if(!e.includes(o))return!1;var u=Object.keys(c).filter((e=>De.has(e)));if(u.length>1)return!1;var h=u[0];if(h&&s.add(o),"$eq"!==h){if(i.length>0)return!1;i.push(h)}}var l=[],d=new Set;for(var[m,f]of Object.entries(t)){if(!e.includes(m))return!1;var p=Object.keys(f).filter((e=>xe.has(e)));if(p.length>1)return!1;var v=p[0];if(v&&d.add(m),"$eq"!==v){if(l.length>0)return!1;l.push(v)}}var y=0;for(var g of e){for(var b of[s,d]){if(!b.has(g)&&b.size>0)return!1;b.delete(g)}if(r[y]!==a[y]&&s.size>0&&d.size>0)return!1;y++}return!0}var _e=r(744),Ie=r(2779),Ee=r(1692),Re=r(4903),Ce=r(7705),Oe=r(2403),Pe=r(1073),Se=r(6950),je=r(6823),$e=!1;function Ne(e){return $e||((0,Ie.DZ)(Ie.hu.PIPELINE,{$sort:Re.xF,$project:Re.C2}),(0,Ie.DZ)(Ie.hu.QUERY,{$and:Ce.a6,$eq:Oe.XV,$elemMatch:Se.Jy,$exists:je.P,$gt:Oe.MR,$gte:Oe.fy,$in:Oe.oZ,$lt:Oe.NV,$lte:Oe.Q_,$ne:Oe.C5,$nin:Oe.GU,$mod:Pe.Pp,$nor:Ce.q3,$not:Ce.En,$or:Ce.sU,$regex:Pe.WP,$size:Se.Ig,$type:je.T}),$e=!0),new Ee.X(e)}function Ae(e,t){var r=T(e.primaryKey);t=s(t);var a=c(t);if("number"!=typeof a.skip&&(a.skip=0),a.selector?(a.selector=a.selector,Object.entries(a.selector).forEach((e=>{let[t,r]=e;"object"==typeof r&&null!==r||(a.selector[t]={$eq:r})}))):a.selector={},a.index){var n=g(a.index);n.includes(r)||n.push(r),a.index=n}if(a.sort)a.sort.find((e=>{return t=e,Object.keys(t)[0]===r;var t}))||(a.sort=a.sort.slice(0),a.sort.push({[r]:"asc"}));else if(a.index)a.sort=a.index.map((e=>({[e]:"asc"})));else{if(e.indexes){var i=new Set;Object.entries(a.selector).forEach((e=>{let[t,r]=e;("object"!=typeof r||null===r||!!Object.keys(r).find((e=>we.has(e))))&&i.add(t)}));var o,u=-1;e.indexes.forEach((e=>{var t=b(e)?e:[e],r=t.findIndex((e=>!i.has(e)));r>0&&r>u&&(u=r,o=t)})),o&&(a.sort=o.map((e=>({[e]:"asc"}))))}a.sort||(a.sort=[{[r]:"asc"}])}return a}function Be(e,t){if(!t.sort)throw S("SNH",{query:t});var r=[];t.sort.forEach((e=>{var t,a,n,i=Object.keys(e)[0],s=Object.values(e)[0];r.push({key:i,direction:s,getValueFn:(t=i,a=t.split("."),n=a.length,1===n?e=>e[t]:e=>{for(var t=e,r=0;r{for(var a=0;ar.test(e)}async function qe(e,t){var r=await e.exec();return r?Array.isArray(r)?Promise.all(r.map((e=>t(e)))):r instanceof Map?Promise.all([...r.values()].map((e=>t(e)))):await t(r):null}function Te(e,t){if(!t.sort)throw S("SNH",{query:t});return{query:t,queryPlan:be(e,t)}}function Le(e){return e===ge?-1/0:e}function Qe(e,t,r){return e.includes(t)?r===ye||!0===r?"1":"0":r}function Fe(e,t,r){if(!r){if("undefined"==typeof window)throw new Error("IDBKeyRange missing");r=window.IDBKeyRange}var a=t.startKeys.map(((r,a)=>{var n=t.index[a];return Qe(e,n,r)})).map(Le),n=t.endKeys.map(((r,a)=>{var n=t.index[a];return Qe(e,n,r)})).map(Le);return r.bound(a,n,!t.inclusiveStart,!t.inclusiveEnd)}async function We(e,t){var r=await e.internals,a=t.query,n=a.skip?a.skip:0,i=n+(a.limit?a.limit:1/0),s=t.queryPlan,o=!1;s.selectorSatisfiedByIndex||(o=Me(e.schema,t.query));var c=Fe(r.booleanIndexes,s,r.dexieDb._options.IDBKeyRange),u=s.index,h=[];if(await r.dexieDb.transaction("r",r.dexieTable,(async e=>{var t,a=e.idbtrans.objectStore(H);t="["+u.map((e=>Y(e))).join("+")+"]";var n=a.index(t).openCursor(c);await new Promise((e=>{n.onsuccess=function(t){var a=t.target.result;if(a){var n=ee(r.booleanIndexes,a.value);o&&!o(n)||h.push(n),s.sortSatisfiedByIndex&&h.length===i?e():a.continue()}else e()}}))})),!s.sortSatisfiedByIndex){var l=Be(e.schema,t.query);h=h.sort(l)}return{documents:h=h.slice(n,i)}}function He(e){for(var t="",r=0;r0&&ze[e].forEach((e=>e(t)))}async function Ue(e,t){for(var r of ze[e])await r(t)}var Ve="_rxdb_internal";async function Je(e,t){var r=(await e.findDocumentsById([t],!1))[0];return r||void 0}async function Ye(e,t,r){var a=await e.bulkWrite([t],r);if(a.error.length>0)throw a.error[0];return it(T(e.schema.primaryKey),[t],a)[0]}function Ge(e,t,r,a){if(a)throw 409===a.status?S("CONFLICT",{collection:e.name,id:t,writeError:a,data:r}):422===a.status?S("VD2",{collection:e.name,id:t,writeError:a,data:r}):a}function Xe(e){return{previous:e.previous,document:et(e.document)}}function et(e){if(!e._attachments||0===Object.keys(e._attachments).length)return e;var t=s(e);return t._attachments={},Object.entries(e._attachments).forEach((e=>{let[r,a]=e;var n,i,s;t._attachments[r]=(s=(n=a).data)?{length:(i=s,atob(i).length),digest:n.digest,type:n.type}:n})),t}function tt(e){return Object.assign({},e,{_meta:s(e._meta)})}function rt(e,t,r){I.deepFreezeWhenDevMode(r);var a=T(t.schema.primaryKey),n={originalStorageInstance:t,schema:t.schema,internals:t.internals,collectionName:t.collectionName,databaseName:t.databaseName,options:t.options,async bulkWrite(r,n){for(var i=e.token,s=new Array(r.length),o=ue(),c=0;ct.bulkWrite(s,n))),m={error:[]};at.set(m,s);var f=0===d.error.length?[]:d.error.filter((e=>!(409!==e.status||e.writeRow.previous||e.writeRow.document._deleted||!(0,ve.ZN)(e.documentInDb)._deleted)||(m.error.push(e),!1)));if(f.length>0){var p=new Set,v=f.map((t=>(p.add(t.documentId),{previous:t.documentInDb,document:Object.assign({},t.writeRow.document,{_rev:Ke(e.token,t.documentInDb)})}))),y=await e.lockedRun((()=>t.bulkWrite(v,n)));return D(m.error,y.error),D(it(a,s,m,p),it(a,v,y)),m}return m},query:r=>e.lockedRun((()=>t.query(r))),count:r=>e.lockedRun((()=>t.count(r))),findDocumentsById:(r,a)=>e.lockedRun((()=>t.findDocumentsById(r,a))),getAttachmentData:(r,a,n)=>e.lockedRun((()=>t.getAttachmentData(r,a,n))),getChangedDocumentsSince:t.getChangedDocumentsSince?(r,a)=>e.lockedRun((()=>t.getChangedDocumentsSince((0,ve.ZN)(r),a))):void 0,cleanup:r=>e.lockedRun((()=>t.cleanup(r))),remove:()=>(e.storageInstances.delete(n),e.lockedRun((()=>t.remove()))),close:()=>(e.storageInstances.delete(n),e.lockedRun((()=>t.close()))),changeStream:()=>t.changeStream()};return e.storageInstances.add(n),n}var at=new WeakMap,nt=new WeakMap;function it(e,t,r,a){return i(nt,r,(()=>{var n=[],i=at.get(r);if(i||(i=t),r.error.length>0||a){for(var s=a||new Set,o=0;o{r.storageName===e&&r.databaseName===t.databaseName&&r.collectionName===t.collectionName&&r.version===t.schema.version&&i.next(r.eventBulk)};n.addEventListener("message",s);var o=r.changeStream(),c=!1,u=o.subscribe((r=>{c||n.postMessage({storageName:e,databaseName:t.databaseName,collectionName:t.collectionName,version:t.schema.version,eventBulk:r})}));r.changeStream=function(){return i.asObservable().pipe((0,st.X)(o))};var h=r.close.bind(r);r.close=async function(){return c=!0,u.unsubscribe(),n.removeEventListener("message",s),a||await ut(t.databaseInstanceToken,r),h()};var l=r.remove.bind(r);r.remove=async function(){return c=!0,u.unsubscribe(),n.removeEventListener("message",s),a||await ut(t.databaseInstanceToken,r),l()}}}var lt=ue(),dt=!1,mt=function(){function e(e,t,r,a,n,i,s,o){this.changes$=new oe.B,this.instanceId=lt++,this.storage=e,this.databaseName=t,this.collectionName=r,this.schema=a,this.internals=n,this.options=i,this.settings=s,this.devMode=o,this.primaryPath=T(this.schema.primaryKey)}var t=e.prototype;return t.bulkWrite=async function(e,t){pt(this),dt||await pe()||console.warn(["-------------- RxDB Open Core RxStorage -------------------------------","You are using the free Dexie.js based RxStorage implementation from RxDB https://rxdb.info/rx-storage-dexie.html?console=dexie ","While this is a great option, we want to let you know that there are faster storage solutions available in our premium plugins.","For professional users and production environments, we highly recommend considering these premium options to enhance performance and reliability."," https://rxdb.info/premium/?console=dexie ","If you already purchased premium access you can disable this log by calling the setPremiumFlag() function from rxdb-premium/plugins/shared.","---------------------------------------------------------------------"].join("\n")),dt=!0,e.forEach((e=>{if(!e.document._rev||e.previous&&!e.previous._rev)throw S("SNH",{args:{row:e}})}));var r=await this.internals,a={error:[]};this.devMode&&(e=e.map((e=>{var t=tt(e.document);return{previous:e.previous,document:t}})));var n,i=e.map((e=>e.document[this.primaryPath]));if(await r.dexieDb.transaction("rw",r.dexieTable,r.dexieAttachmentsTable,(async()=>{var s=new Map;(await ne(this.internals,i)).forEach((e=>{var t=e;return t&&s.set(t[this.primaryPath],t),t})),n=function(e,t,r,a,n,i,s){for(var o,c=!!e.schema.attachments,u=[],h=[],l=[],d={id:(0,M.zs)(10),events:[],checkpoint:null,context:n},m=d.events,f=[],p=[],v=[],y=r.size>0,g=a.length,b=function(){var e,n=a[w],d=n.document,g=n.previous,b=d[t],D=d._deleted,x=g&&g._deleted,k=void 0;if(y&&(k=r.get(b)),k){var _=k._rev;if(!g||g&&_!==g._rev){var I={isError:!0,status:409,documentId:b,writeRow:n,documentInDb:k};return l.push(I),1}var E=c?Xe(n):n;c&&(D?g&&Object.keys(g._attachments).forEach((e=>{p.push({documentId:b,attachmentId:e,digest:(0,ve.ZN)(g)._attachments[e].digest})})):(Object.entries(d._attachments).find((t=>{let[r,a]=t;return(g?g._attachments[r]:void 0)||a.data||(e={documentId:b,documentInDb:k,isError:!0,status:510,writeRow:n,attachmentId:r}),!0})),e||Object.entries(d._attachments).forEach((e=>{let[t,r]=e;var a=g?g._attachments[t]:void 0;if(a){var n=E.document._attachments[t].digest;r.data&&a.digest!==n&&v.push({documentId:b,attachmentId:t,attachmentData:r,digest:r.digest})}else f.push({documentId:b,attachmentId:t,attachmentData:r,digest:r.digest})})))),e?l.push(e):(c?(h.push(Xe(E)),s&&s(d)):(h.push(E),s&&s(d)),o=E);var R=null,C=null,O=null;if(x&&!D)O="INSERT",R=c?et(d):d;else if(!g||x||D){if(!D)throw S("SNH",{args:{writeRow:n}});O="DELETE",R=(0,ve.ZN)(d),C=g}else O="UPDATE",R=c?et(d):d,C=g;var P={documentId:b,documentData:R,previousDocumentData:C,operation:O};m.push(P)}else{var j=!!D;if(c&&Object.entries(d._attachments).forEach((t=>{let[r,a]=t;a.data?f.push({documentId:b,attachmentId:r,attachmentData:a,digest:a.digest}):(e={documentId:b,isError:!0,status:510,writeRow:n,attachmentId:r},l.push(e))})),e||(c?(u.push(Xe(n)),i&&i(d)):(u.push(n),i&&i(d)),o=n),!j){var $={documentId:b,operation:"INSERT",documentData:c?et(d):d,previousDocumentData:c&&g?et(g):g};m.push($)}}},w=0;w{o.push(e.document)})),n.bulkUpdateDocs.forEach((e=>{o.push(e.document)})),(o=o.map((e=>X(r.booleanIndexes,e)))).length>0&&await r.dexieTable.bulkPut(o);var c=[];n.attachmentsAdd.forEach((e=>{c.push({id:ie(e.documentId,e.attachmentId),data:e.attachmentData.data})})),n.attachmentsUpdate.forEach((e=>{c.push({id:ie(e.documentId,e.attachmentId),data:e.attachmentData.data})})),await r.dexieAttachmentsTable.bulkPut(c),await r.dexieAttachmentsTable.bulkDelete(n.attachmentsRemove.map((e=>ie(e.documentId,e.attachmentId))))})),(n=(0,ve.ZN)(n)).eventBulk.events.length>0){var s=(0,ve.ZN)(n.newestRow).document;n.eventBulk.checkpoint={id:s[this.primaryPath],lwt:s._meta.lwt},this.changes$.next(n.eventBulk)}return a},t.findDocumentsById=async function(e,t){pt(this);var r=await this.internals,a=[];return await r.dexieDb.transaction("r",r.dexieTable,(async()=>{(await ne(this.internals,e)).forEach((e=>{!e||e._deleted&&!t||a.push(e)}))})),a},t.query=function(e){return pt(this),We(this,e)},t.count=async function(e){if(e.queryPlan.selectorSatisfiedByIndex){var t=await async function(e,t){var r=await e.internals,a=t.queryPlan,n=a.index,i=Fe(r.booleanIndexes,a,r.dexieDb._options.IDBKeyRange),s=-1;return await r.dexieDb.transaction("r",r.dexieTable,(async e=>{var t,r=e.idbtrans.objectStore(H);t="["+n.map((e=>Y(e))).join("+")+"]";var a=r.index(t).count(i);s=await new Promise(((e,t)=>{a.onsuccess=function(){e(a.result)},a.onerror=e=>t(e)}))})),s}(this,e);return{count:t,mode:"fast"}}return{count:(await We(this,e)).documents.length,mode:"slow"}},t.changeStream=function(){return pt(this),this.changes$.asObservable()},t.cleanup=async function(e){pt(this);var t=await this.internals;return await t.dexieDb.transaction("rw",t.dexieTable,(async()=>{var r=ue()-e,a=await t.dexieTable.where("_meta.lwt").below(r).toArray(),n=[];a.forEach((e=>{"1"===e._deleted&&n.push(e[this.primaryPath])})),await t.dexieTable.bulkDelete(n)})),!0},t.getAttachmentData=async function(e,t,r){pt(this);var a=await this.internals,n=ie(e,t);return await a.dexieDb.transaction("r",a.dexieAttachmentsTable,(async()=>{var r=await a.dexieAttachmentsTable.get(n);if(r)return r.data;throw new Error("attachment missing documentId: "+e+" attachmentId: "+t)}))},t.remove=async function(){pt(this);var e=await this.internals;return await e.dexieTable.clear(),this.close()},t.close=function(){return this.closed||(this.closed=(async()=>{this.changes$.complete(),await async function(e){var t=await e,r=V.get(e)-1;0===r?(t.dexieDb.close(),V.delete(e)):V.set(e,r)}(this.internals)})()),this.closed},e}();async function ft(e,t,r){var n=function(e,t,r,n){var o="rxdb-dexie-"+e+"--"+n.version+"--"+t,c=i(U,o,(()=>{var e=(async()=>{var e=s(r);e.autoOpen=!1;var t=new a.cf(o,e),i={[H]:ae(n),[K]:"++sequence, id",[z]:"id"};return t.version(1).stores(i),await t.open(),{dexieDb:t,dexieTable:t[H],dexieAttachmentsTable:t[z],booleanIndexes:se(n)}})();return U.set(o,c),V.set(c,0),e}));return c}(t.databaseName,t.collectionName,r,t.schema),o=new mt(e,t.databaseName,t.collectionName,t.schema,n,t.options,r,t.devMode);return await ht(Z,t,o),Promise.resolve(o)}function pt(e){if(e.closed)throw new Error("RxStorageInstanceDexie is closed "+e.databaseName+"-"+e.collectionName)}var vt="16.6.1",yt=function(){function e(e){this.name=Z,this.rxdbVersion=vt,this.settings=e}return e.prototype.createStorageInstance=function(e){(function(e){if(e.schema.keyCompression)throw S("UT5",{args:{params:e}});if((t=e.schema).encrypted&&t.encrypted.length>0||t.attachments&&t.attachments.encrypted)throw S("UT6",{args:{params:e}});var t;if(e.schema.attachments&&e.schema.attachments.compression)throw S("UT7",{args:{params:e}})}(e),e.schema.indexes)&&e.schema.indexes.flat().filter((e=>!e.includes("."))).forEach((t=>{if(!e.schema.required||!e.schema.required.includes(t))throw S("DXE1",{field:t,schema:e.schema})}));return ft(this,e,this.settings)},e}();var gt=r(7593),bt=function(){function e(e,t){if(this.jsonSchema=e,this.hashFunction=t,this.indexes=function(e){return(e.indexes||[]).map((e=>b(e)?e:[e]))}(this.jsonSchema),this.primaryPath=T(this.jsonSchema.primaryKey),!e.properties[this.primaryPath].maxLength)throw S("SC39",{schema:e});this.finalFields=W(this.jsonSchema)}var t=e.prototype;return t.validateChange=function(e,t){this.finalFields.forEach((r=>{if(!(0,gt.b)(e[r],t[r]))throw S("DOC9",{dataBefore:e,dataAfter:t,fieldName:r,schema:this.jsonSchema})}))},t.getDocumentPrototype=function(){var e={},t=q(this.jsonSchema,"");return Object.keys(t).forEach((t=>{var r=t;e.__defineGetter__(t,(function(){if(this.get&&"function"==typeof this.get)return this.get(r)})),Object.defineProperty(e,t+"$",{get:function(){return this.get$(r)},enumerable:!1,configurable:!1}),Object.defineProperty(e,t+"$$",{get:function(){return this.get$$(r)},enumerable:!1,configurable:!1}),Object.defineProperty(e,t+"_",{get:function(){return this.populate(r)},enumerable:!1,configurable:!1})})),u(this,"getDocumentPrototype",(()=>e)),e},t.getPrimaryOfDocumentData=function(e){return L(this.jsonSchema,e)},(0,x.A)(e,[{key:"version",get:function(){return this.jsonSchema.version}},{key:"defaultValues",get:function(){var e={};return Object.entries(this.jsonSchema.properties).filter((e=>{let[,t]=e;return Object.prototype.hasOwnProperty.call(t,"default")})).forEach((t=>{let[r,a]=t;return e[r]=a.default})),u(this,"defaultValues",e)}},{key:"hash",get:function(){return u(this,"hash",this.hashFunction(JSON.stringify(this.jsonSchema)))}}])}();function wt(e,t,r){void 0===r&&(r=!0),r&&Ze("preCreateRxSchema",e);var a=Q(e);a=function(e){return o(e,!0)}(a),I.deepFreezeWhenDevMode(a);var n=new bt(a,t);return Ze("createRxSchema",n),n}var Dt=r(7708),xt=r(8146),kt=r(3356),_t=r(5520),It=r(8609);function Et(e){var t=e.split("-"),r="RxDB";return t.forEach((e=>{r+=(0,M.Z2)(e)})),r+="Plugin",new Error("You are using a function which must be overwritten by a plugin.\n You should either prevent the usage of this function or add the plugin via:\n import { "+r+" } from 'rxdb/plugins/"+e+"';\n addRxPlugin("+r+");\n ")}function Rt(e){return e.documentData?e.documentData:e.previousDocumentData}function Ct(e){switch(e.operation){case"INSERT":return{operation:e.operation,id:e.documentId,doc:e.documentData,previous:null};case"UPDATE":return{operation:e.operation,id:e.documentId,doc:I.deepFreezeWhenDevMode(e.documentData),previous:e.previousDocumentData?e.previousDocumentData:"UNKNOWN"};case"DELETE":return{operation:e.operation,id:e.documentId,doc:null,previous:e.previousDocumentData}}}var Ot=new Map;function Pt(e){return i(Ot,e,(()=>{for(var t=new Array(e.events.length),r=e.events,a=e.collectionName,n=e.isLocal,i=I.deepFreezeWhenDevMode,s=0;s[]));return new Promise(((r,n)=>{var i={lastKnownDocumentState:e,modifier:t,resolve:r,reject:n};(0,ve.ZN)(a).push(i),this.triggerRun()}))},t.triggerRun=async function(){if(!0!==this.isRunning&&0!==this.queueByDocId.size){this.isRunning=!0;var e=[],t=this.queueByDocId;this.queueByDocId=new Map,await Promise.all(Array.from(t.entries()).map((async t=>{let[r,a]=t;var n,i,s,o=(n=a.map((e=>e.lastKnownDocumentState)),i=n[0],s=He(i._rev),n.forEach((e=>{var t=He(e._rev);t>s&&(i=e,s=t)})),i),u=o;for(var h of a)try{u=await h.modifier(c(u))}catch(l){h.reject(l),h.reject=()=>{},h.resolve=()=>{}}try{await this.preWrite(u,o)}catch(l){return void a.forEach((e=>e.reject(l)))}e.push({previous:o,document:u})})));var r=e.length>0?await this.storageInstance.bulkWrite(e,"incremental-write"):{error:[]};return await Promise.all(it(this.primaryPath,e,r).map((e=>{var r=e[this.primaryPath];this.postWrite(e),n(t,r).forEach((t=>t.resolve(e)))}))),r.error.forEach((e=>{var r=e.documentId,a=n(t,r),s=$(e);if(s){var o=i(this.queueByDocId,r,(()=>[]));a.reverse().forEach((e=>{e.lastKnownDocumentState=(0,ve.ZN)(s.documentInDb),(0,ve.ZN)(o).unshift(e)}))}else{var c=A(e);a.forEach((e=>e.reject(c)))}})),this.isRunning=!1,this.triggerRun()}},e}();function jt(e){return async t=>{var r=function(e){return Object.assign({},e,{_meta:void 0,_deleted:void 0,_rev:void 0})}(t);r._deleted=t._deleted;var a=await e(r),n=Object.assign({},a,{_meta:t._meta,_attachments:t._attachments,_rev:t._rev,_deleted:void 0!==a._deleted?a._deleted:t._deleted});return void 0===n._deleted&&(n._deleted=!1),n}}var $t={get primaryPath(){if(this.isInstanceOfRxDocument)return this.collection.schema.primaryPath},get primary(){var e=this;if(e.isInstanceOfRxDocument)return e._data[e.primaryPath]},get revision(){if(this.isInstanceOfRxDocument)return this._data._rev},get deleted$(){if(this.isInstanceOfRxDocument)return this.$.pipe((0,Dt.T)((e=>e._data._deleted)))},get deleted$$(){var e=this;return e.collection.database.getReactivityFactory().fromObservable(e.deleted$,e.getLatest().deleted,e.collection.database)},get deleted(){if(this.isInstanceOfRxDocument)return this._data._deleted},getLatest(){var e=this.collection._docCache.getLatestDocumentData(this.primary);return this.collection._docCache.getCachedRxDocument(e)},get $(){var e=this.primary;return this.collection.eventBulks$.pipe((0,xt.p)((e=>!e.isLocal)),(0,Dt.T)((t=>t.events.find((t=>t.documentId===e)))),(0,xt.p)((e=>!!e)),(0,Dt.T)((e=>Rt((0,ve.ZN)(e)))),(0,kt.Z)(this.collection._docCache.getLatestDocumentData(e)),(0,_t.F)(((e,t)=>e._rev===t._rev)),(0,Dt.T)((e=>this.collection._docCache.getCachedRxDocument(e))),(0,It.t)(ve.bz))},get $$(){var e=this;return e.collection.database.getReactivityFactory().fromObservable(e.$,e.getLatest()._data,e.collection.database)},get$(e){if(I.isDevMode()){if(e.includes(".item."))throw S("DOC1",{path:e});if(e===this.primaryPath)throw S("DOC2");if(this.collection.schema.finalFields.includes(e))throw S("DOC3",{path:e});if(!q(this.collection.schema.jsonSchema,e))throw S("DOC4",{path:e})}return this.$.pipe((0,Dt.T)((t=>v(t,e))),(0,_t.F)())},get$$(e){var t=this.get$(e);return this.collection.database.getReactivityFactory().fromObservable(t,this.getLatest().get(e),this.collection.database)},populate(e){var t=q(this.collection.schema.jsonSchema,e),r=this.get(e);if(!r)return de.$A;if(!t)throw S("DOC5",{path:e});if(!t.ref)throw S("DOC6",{path:e,schemaObj:t});var a=this.collection.database.collections[t.ref];if(!a)throw S("DOC7",{ref:t.ref,path:e,schemaObj:t});return"array"===t.type?a.findByIds(r).exec().then((e=>{var t=e.values();return Array.from(t)})):a.findOne(r).exec()},get(e){return Bt(this,e)},toJSON(e){if(void 0===e&&(e=!1),e)return I.deepFreezeWhenDevMode(this._data);var t=s(this._data);return delete t._rev,delete t._attachments,delete t._deleted,delete t._meta,I.deepFreezeWhenDevMode(t)},toMutableJSON(e){return void 0===e&&(e=!1),c(this.toJSON(e))},update(e){throw Et("update")},incrementalUpdate(e){throw Et("update")},updateCRDT(e){throw Et("crdt")},putAttachment(){throw Et("attachments")},getAttachment(){throw Et("attachments")},allAttachments(){throw Et("attachments")},get allAttachments$(){throw Et("attachments")},async modify(e,t){var r=this._data,a=await jt(e)(r);return this._saveData(a,r)},incrementalModify(e,t){return this.collection.incrementalWriteQueue.addWrite(this._data,jt(e)).then((e=>this.collection._docCache.getCachedRxDocument(e)))},patch(e){var t=this._data,r=c(t);return Object.entries(e).forEach((e=>{let[t,a]=e;r[t]=a})),this._saveData(r,t)},incrementalPatch(e){return this.incrementalModify((t=>(Object.entries(e).forEach((e=>{let[r,a]=e;t[r]=a})),t)))},async _saveData(e,t){if(e=s(e),this._data._deleted)throw S("DOC11",{id:this.primary,document:this});await At(this.collection,e,t);var r=[{previous:t,document:e}],a=await this.collection.storageInstance.bulkWrite(r,"rx-document-save-data"),n=a.error[0];return Ge(this.collection,this.primary,e,n),await this.collection._runHooks("post","save",e,this),this.collection._docCache.getCachedRxDocument(it(this.collection.schema.primaryPath,r,a)[0])},async remove(){if(this.deleted)return Promise.reject(S("DOC13",{document:this,id:this.primary}));var e=await this.collection.bulkRemove([this]);if(e.error.length>0){var t=e.error[0];Ge(this.collection,this.primary,this._data,t)}return e.success[0]},incrementalRemove(){return this.incrementalModify((async e=>(await this.collection._runHooks("pre","remove",e,this),e._deleted=!0,e))).then((async e=>(await this.collection._runHooks("post","remove",e._data,e),e)))},close(){throw S("DOC14")}};function Nt(e){void 0===e&&(e=$t);var t=function(e,t){this.collection=e,this._data=t,this._propertyCache=new Map,this.isInstanceOfRxDocument=!0};return t.prototype=e,t}function At(e,t,r){return t._meta=Object.assign({},r._meta,t._meta),I.isDevMode()&&e.schema.validateChange(r,t),e._runHooks("pre","save",t,r)}function Bt(e,t){return i(e._propertyCache,t,(()=>{var r=v(e._data,t);return"object"!=typeof r||null===r||Array.isArray(r)?I.deepFreezeWhenDevMode(r):new Proxy(s(r),{get(r,a){if("string"!=typeof a)return r[a];var n=a.charAt(a.length-1);if("$"===n){if(a.endsWith("$$")){var i=a.slice(0,-2);return e.get$$((0,M.L$)(t+"."+i))}var s=a.slice(0,-1);return e.get$((0,M.L$)(t+"."+s))}if("_"===n){var o=a.slice(0,-1);return e.populate((0,M.L$)(t+"."+o))}var c=r[a];return"number"==typeof c||"string"==typeof c||"boolean"==typeof c?c:Bt(e,(0,M.L$)(t+"."+a))}})}))}var Mt=r(2198),qt=r(4157),Tt=r(2442),Lt=r(6114);function Qt(e,t){return t.sort&&0!==t.sort.length?t.sort.map((e=>Object.keys(e)[0])):[e]}var Ft=new WeakMap;function Wt(e,t){if(!e.collection.database.eventReduce)return{runFullQueryAgain:!0};for(var r=function(e){return i(Ft,e,(()=>{var t=e.collection,r=Ae(t.storageInstance.schema,c(e.mangoQuery)),a=t.schema.primaryPath,n=Be(t.schema.jsonSchema,r),i=Me(t.schema.jsonSchema,r);return{primaryKey:e.collection.schema.primaryPath,skip:r.skip,limit:r.limit,sortFields:Qt(a,r),sortComparator:(t,r)=>{var a={docA:t,docB:r,rxQuery:e};return n(a.docA,a.docB)},queryMatcher:t=>i({doc:t,rxQuery:e}.doc)}}))}(e),a=(0,ve.ZN)(e._result).docsData.slice(0),n=(0,ve.ZN)(e._result).docsDataMap,s=!1,o=[],u=0;u{var t={queryParams:r,changeEvent:e,previousResults:a,keyDocumentMap:n},i=(0,Lt.kC)(t);return"runFullQueryAgain"===i||("doNothing"!==i?(s=!0,(0,Lt.Cs)(i,r,e,a,n),!1):void 0)}));return l?{runFullQueryAgain:!0}:{runFullQueryAgain:!1,changed:s,newResults:a}}var Ht=function(){function e(){this._map=new Map}return e.prototype.getByQuery=function(e){var t=e.toString();return i(this._map,t,(()=>e))},e}();function Kt(e,t){t.uncached=!0;var r=t.toString();e._map.delete(r)}function zt(e){return e.refCount$.observers.length}var Zt,Ut,Vt=(Zt=100,Ut=3e4,(e,t)=>{if(!(t._map.size0||(0===i._lastEnsureEqual&&i._creationTimee._lastEnsureEqual-t._lastEnsureEqual)).slice(0,s).forEach((e=>Kt(t,e)))}}),Jt=new WeakSet;var Yt=function(){function e(e,t,r){this.cacheItemByDocId=new Map,this.tasks=new Set,this.registry="function"==typeof FinalizationRegistry?new FinalizationRegistry((e=>{var t=e.docId,r=this.cacheItemByDocId.get(t);r&&(r[0].delete(e.revisionHeight),0===r[0].size&&this.cacheItemByDocId.delete(t))})):void 0,this.primaryPath=e,this.changes$=t,this.documentCreator=r,t.subscribe((e=>{this.tasks.add((()=>{for(var t=this.cacheItemByDocId,r=0;r{this.processTasks()}))}))}var t=e.prototype;return t.processTasks=function(){0!==this.tasks.size&&(Array.from(this.tasks).forEach((e=>e())),this.tasks.clear())},t.getLatestDocumentData=function(e){return this.processTasks(),n(this.cacheItemByDocId,e)[1]},t.getLatestDocumentDataIfExists=function(e){this.processTasks();var t=this.cacheItemByDocId.get(e);if(t)return t[1]},(0,x.A)(e,[{key:"getCachedRxDocuments",get:function(){return u(this,"getCachedRxDocuments",Gt(this))}},{key:"getCachedRxDocument",get:function(){var e=Gt(this);return u(this,"getCachedRxDocument",(t=>e([t])[0]))}}])}();function Gt(e){var t=e.primaryPath,r=e.cacheItemByDocId,a=e.registry,n=I.deepFreezeWhenDevMode,i=e.documentCreator;return s=>{for(var o=new Array(s.length),c=[],u=0;u0&&a&&(e.tasks.add((()=>{for(var e=0;e{e.processTasks()}))),o}}function Xt(e,t){return(0,e.getCachedRxDocuments)(t)}var er="function"==typeof WeakRef?function(e){return new WeakRef(e)}:function(e){return{deref:()=>e}};var tr=function(){function e(e,t,r){this.time=ue(),this.query=e,this.count=r,this.documents=Xt(this.query.collection._docCache,t)}return e.prototype.getValue=function(e){var t=this.query.op;if("count"===t)return this.count;if("findOne"===t){var r=0===this.documents.length?null:this.documents[0];if(!r&&e)throw S("QU10",{collection:this.query.collection.name,query:this.query.mangoQuery,op:t});return r}return"findByIds"===t?this.docsMap:this.documents.slice(0)},(0,x.A)(e,[{key:"docsData",get:function(){return u(this,"docsData",this.documents.map((e=>e._data)))}},{key:"docsDataMap",get:function(){var e=new Map;return this.documents.forEach((t=>{e.set(t.primary,t._data)})),u(this,"docsDataMap",e)}},{key:"docsMap",get:function(){for(var e=new Map,t=this.documents,r=0;r"string"!=typeof e)))return r.$eq}return!1}(this.collection.schema.primaryPath,t)}var t=e.prototype;return t._setResultData=function(e){if(void 0===e)throw S("QU18",{database:this.collection.database.name,collection:this.collection.name});if("number"!=typeof e){e instanceof Map&&(e=Array.from(e.values()));var t=new tr(this,e,e.length);this._result=t}else this._result=new tr(this,[],e)},t._execOverDatabase=async function(){if(this._execOverDatabaseCount=this._execOverDatabaseCount+1,"count"===this.op){var e=this.getPreparedQuery(),t=await this.collection.storageInstance.count(e);if("slow"!==t.mode||this.collection.database.allowSlowCount)return t.count;throw S("QU14",{collection:this.collection,queryObj:this.mangoQuery})}if("findByIds"===this.op){var r=(0,ve.ZN)(this.mangoQuery.selector)[this.collection.schema.primaryPath].$in,a=new Map,n=[];if(r.forEach((e=>{var t=this.collection._docCache.getLatestDocumentDataIfExists(e);if(t){if(!t._deleted){var r=this.collection._docCache.getCachedRxDocument(t);a.set(e,r)}}else n.push(e)})),n.length>0)(await this.collection.storageInstance.findDocumentsById(n,!1)).forEach((e=>{var t=this.collection._docCache.getCachedRxDocument(e);a.set(t.primary,t)}));return a}var i=async function(e){var t=[],r=e.collection;if(e.isFindOneByIdQuery)if(Array.isArray(e.isFindOneByIdQuery)){var a=e.isFindOneByIdQuery;if(a=a.filter((r=>{var a=e.collection._docCache.getLatestDocumentDataIfExists(r);return!a||(a._deleted||t.push(a),!1)})),a.length>0){var n=await r.storageInstance.findDocumentsById(a,!1);D(t,n)}}else{var i=e.isFindOneByIdQuery,s=e.collection._docCache.getLatestDocumentDataIfExists(i);if(!s){var o=await r.storageInstance.findDocumentsById([i],!1);o[0]&&(s=o[0])}s&&!s._deleted&&t.push(s)}else{var c=e.getPreparedQuery(),u=await r.storageInstance.query(c);t=u.documents}return t}(this);return i.then((e=>e))},t.exec=async function(e){if(e&&"findOne"!==this.op)throw S("QU9",{collection:this.collection.name,query:this.mangoQuery,op:this.op});return await sr(this),(0,ve.ZN)(this._result).getValue(e)},t.toString=function(){var e=o({op:this.op,query:Ae(this.collection.schema.jsonSchema,this.mangoQuery),other:this.other},!0),t=JSON.stringify(e);return this.toString=()=>t,t},t.getPreparedQuery=function(){var e={rxQuery:this,mangoQuery:Ae(this.collection.schema.jsonSchema,this.mangoQuery)};e.mangoQuery.selector._deleted={$eq:!1},e.mangoQuery.index&&e.mangoQuery.index.unshift("_deleted"),Ze("prePrepareQuery",e);var t=Te(this.collection.schema.jsonSchema,e.mangoQuery);return this.getPreparedQuery=()=>t,t},t.doesDocumentDataMatch=function(e){return!e._deleted&&this.queryMatcher(e)},t.remove=async function(){var e=await this.exec();if(Array.isArray(e)){var t=await this.collection.bulkRemove(e);if(t.error.length>0)throw A(t.error[0]);return t.success}return e.remove()},t.incrementalRemove=function(){return qe(this.asRxQuery,(e=>e.incrementalRemove()))},t.update=function(e){throw Et("update")},t.patch=function(e){return qe(this.asRxQuery,(t=>t.patch(e)))},t.incrementalPatch=function(e){return qe(this.asRxQuery,(t=>t.incrementalPatch(e)))},t.modify=function(e){return qe(this.asRxQuery,(t=>t.modify(e)))},t.incrementalModify=function(e){return qe(this.asRxQuery,(t=>t.incrementalModify(e)))},t.where=function(e){throw Et("query-builder")},t.sort=function(e){throw Et("query-builder")},t.skip=function(e){throw Et("query-builder")},t.limit=function(e){throw Et("query-builder")},(0,x.A)(e,[{key:"$",get:function(){if(!this._$){var e=this.collection.eventBulks$.pipe((0,xt.p)((e=>!e.isLocal)),(0,kt.Z)(null),(0,Tt.Z)((()=>sr(this))),(0,Dt.T)((()=>this._result)),(0,It.t)(ve.bz),(0,_t.F)(((e,t)=>!(!e||e.time!==(0,ve.ZN)(t).time))),(0,xt.p)((e=>!!e)),(0,Dt.T)((e=>(0,ve.ZN)(e).getValue())));this._$=(0,qt.h)(e,this.refCount$.pipe((0,xt.p)((()=>!1))))}return this._$}},{key:"$$",get:function(){return this.collection.database.getReactivityFactory().fromObservable(this.$,void 0,this.collection.database)}},{key:"queryMatcher",get:function(){this.collection.schema.jsonSchema;return u(this,"queryMatcher",Me(0,Ae(this.collection.schema.jsonSchema,this.mangoQuery)))}},{key:"asRxQuery",get:function(){return this}}])}();function nr(e,t,r,a){Ze("preCreateRxQuery",{op:e,queryObj:t,collection:r,other:a});var n,i,s=new ar(e,t,r,a);return s=(n=s).collection._queryCache.getByQuery(n),i=r,Jt.has(i)||(Jt.add(i),(0,de.dY)().then((()=>(0,de.Ve)(200))).then((()=>{i.closed||i.cacheReplacementPolicy(i,i._queryCache),Jt.delete(i)}))),s}function ir(e){var t=e.asRxQuery.collection._changeEventBuffer.getCounter();return e._latestChangeEvent>=t}async function sr(e){return e.collection.awaitBeforeReads.size>0&&await Promise.all(Array.from(e.collection.awaitBeforeReads).map((e=>e()))),!e.collection.database.closed&&!ir(e)&&(e._ensureEqualQueue=e._ensureEqualQueue.then((()=>function(e){if(e._lastEnsureEqual=ue(),e.collection.database.closed||ir(e))return de.Dr;var t=!1,r=!1;-1===e._latestChangeEvent&&(r=!0);if(!r){var a=e.asRxQuery.collection._changeEventBuffer.getFrom(e._latestChangeEvent+1);if(null===a)r=!0;else{e._latestChangeEvent=e.asRxQuery.collection._changeEventBuffer.getCounter();var n=e.asRxQuery.collection._changeEventBuffer.reduceByLastOfDoc(a);if("count"===e.op){var i=(0,ve.ZN)(e._result).count,s=i;n.forEach((t=>{var r=t.previousDocumentData&&e.doesDocumentDataMatch(t.previousDocumentData),a=e.doesDocumentDataMatch(t.documentData);!r&&a&&s++,r&&!a&&s--})),s!==i&&(t=!0,e._setResultData(s))}else{var o=Wt(e,n);o.runFullQueryAgain?r=!0:o.changed&&(t=!0,e._setResultData(o.newResults))}}}if(r)return e._execOverDatabase().then((r=>(e._latestChangeEvent=e.collection._changeEventBuffer.getCounter(),"number"==typeof r?(e._result&&r===e._result.count||(t=!0,e._setResultData(r)),t):(e._result&&function(e,t,r){if(t.length!==r.length)return!1;for(var a=0,n=t.length;ae.data.name===n)),u=[];c.forEach((e=>{u.push({collectionName:e.data.name,schema:e.data.schema,isCollection:!0}),e.data.connectedStorages.forEach((e=>u.push({collectionName:e.collectionName,isCollection:!1,schema:e.schema})))}));var h=new Set;if(u=u.filter((e=>{var t=e.collectionName+"||"+e.schema.version;return!h.has(t)&&(h.add(t),!0)})),await Promise.all(u.map((async t=>{var o=await e.createStorageInstance({collectionName:t.collectionName,databaseInstanceToken:r,databaseName:a,multiInstance:i,options:{},schema:t.schema,password:s,devMode:I.isDevMode()});await o.remove(),t.isCollection&&await Ue("postRemoveRxCollection",{storage:e,databaseName:a,collectionName:n})}))),o){var l=c.map((e=>{var t=tt(e);return t._deleted=!0,t._meta.lwt=ue(),t._rev=Ke(r,e),{previous:e,document:t}}));await t.bulkWrite(l,"rx-database-remove-collection-all")}}function yr(e){if(e.closed)throw S("COL21",{collection:e.name,version:e.schema.version})}var gr=function(){function e(e){this.subs=[],this.counter=0,this.eventCounterMap=new WeakMap,this.buffer=[],this.limit=100,this.tasks=new Set,this.collection=e,this.subs.push(this.collection.eventBulks$.pipe((0,xt.p)((e=>!e.isLocal))).subscribe((e=>{this.tasks.add((()=>this._handleChangeEvents(e.events))),this.tasks.size<=1&&(0,de.vN)().then((()=>{this.processTasks()}))})))}var t=e.prototype;return t.processTasks=function(){0!==this.tasks.size&&(Array.from(this.tasks).forEach((e=>e())),this.tasks.clear())},t._handleChangeEvents=function(e){var t=this.counter;this.counter=this.counter+e.length,e.length>this.limit?this.buffer=e.slice(-1*e.length):(D(this.buffer,e),this.buffer=this.buffer.slice(-1*this.limit));for(var r=t+1,a=this.eventCounterMap,n=0;nt(e)))},t.reduceByLastOfDoc=function(e){return this.processTasks(),e.slice(0)},t.close=function(){this.tasks.clear(),this.subs.forEach((e=>e.unsubscribe()))},e}();var br=new WeakMap;function wr(e){var t=e.schema.getDocumentPrototype(),r=function(e){var t={};return Object.entries(e.methods).forEach((e=>{let[r,a]=e;t[r]=a})),t}(e),a={};return[t,r,$t].forEach((e=>{Object.getOwnPropertyNames(e).forEach((t=>{var r=Object.getOwnPropertyDescriptor(e,t),n=!0;(t.startsWith("_")||t.endsWith("_")||t.startsWith("$")||t.endsWith("$"))&&(n=!1),"function"==typeof r.value?Object.defineProperty(a,t,{get(){return r.value.bind(this)},enumerable:n,configurable:!1}):(r.enumerable=n,r.configurable=!1,r.writable&&(r.writable=!1),Object.defineProperty(a,t,r))}))})),a}function Dr(e,t,r){var a=function(e,t,r){var a=new e(t,r);return Ze("createRxDocument",a),a}(t,e,I.deepFreezeWhenDevMode(r));return e._runHooksSync("post","create",r,a),Ze("postCreateRxDocument",a),a}var xr={isEqual:(e,t)=>(0,gt.b)(et(e),et(t)),resolve:e=>e.realMasterState},kr=["pre","post"],_r=["insert","save","remove","create"],Ir=!1,Er=new Set,Rr=function(){function e(e,t,r,a,n,i,s,o,c,u,h,l){void 0===n&&(n={}),void 0===i&&(i={}),void 0===s&&(s={}),void 0===o&&(o={}),void 0===c&&(c={}),void 0===u&&(u=Vt),void 0===h&&(h={}),void 0===l&&(l=xr),this.storageInstance={},this.timeouts=new Set,this.incrementalWriteQueue={},this.awaitBeforeReads=new Set,this._incrementalUpsertQueues=new Map,this.synced=!1,this.hooks={},this._subs=[],this._docCache={},this._queryCache=new Ht,this.$={},this.checkpoint$={},this._changeEventBuffer={},this.eventBulks$={},this.onClose=[],this.closed=!1,this.onRemove=[],this.database=e,this.name=t,this.schema=r,this.internalStorageInstance=a,this.instanceCreationOptions=n,this.migrationStrategies=i,this.methods=s,this.attachments=o,this.options=c,this.cacheReplacementPolicy=u,this.statics=h,this.conflictHandler=l,function(e){if(Ir)return;Ir=!0;var t=Object.getPrototypeOf(e);_r.forEach((e=>{kr.map((r=>{var a=r+(0,M.Z2)(e);t[a]=function(t,a){return this.addHook(r,e,t,a)}}))}))}(this.asRxCollection),e&&(this.eventBulks$=e.eventBulks$.pipe((0,xt.p)((e=>e.collectionName===this.name)))),this.database&&Er.add(this)}var t=e.prototype;return t.prepare=async function(){if(!await pe()){for(var e=0;e<10&&Er.size>16;)e++,await this.promiseWait(30);if(Er.size>16)throw S("COL23",{database:this.database.name,collection:this.name,args:{existing:Array.from(Er.values()).map((e=>({db:e.database?e.database.name:"",c:e.name})))}})}var t,r;this.storageInstance=rt(this.database,this.internalStorageInstance,this.schema.jsonSchema),this.incrementalWriteQueue=new St(this.storageInstance,this.schema.primaryPath,((e,t)=>At(this,e,t)),(e=>this._runHooks("post","save",e))),this.$=this.eventBulks$.pipe((0,Tt.Z)((e=>Pt(e)))),this.checkpoint$=this.eventBulks$.pipe((0,Dt.T)((e=>e.checkpoint))),this._changeEventBuffer=(t=this.asRxCollection,new gr(t)),this._docCache=new Yt(this.schema.primaryPath,this.eventBulks$.pipe((0,xt.p)((e=>!e.isLocal)),(0,Dt.T)((e=>e.events))),(e=>{var t;return r||(t=this.asRxCollection,r=i(br,t,(()=>Nt(wr(t))))),Dr(this.asRxCollection,r,e)}));var a=this.database.internalStore.changeStream().pipe((0,xt.p)((e=>{var t=this.name+"-"+this.schema.version;return!!e.events.find((e=>"collection"===e.documentData.context&&e.documentData.key===t&&"DELETE"===e.operation))}))).subscribe((async()=>{await this.close(),await Promise.all(this.onRemove.map((e=>e())))}));this._subs.push(a);var n=await this.database.storageToken,s=this.storageInstance.changeStream().subscribe((e=>{var t={id:e.id,isLocal:!1,internal:!1,collectionName:this.name,storageToken:n,events:e.events,databaseToken:this.database.token,checkpoint:e.checkpoint,context:e.context};this.database.$emit(t)}));return this._subs.push(s),de.em},t.cleanup=function(e){throw yr(this),Et("cleanup")},t.migrationNeeded=function(){throw Et("migration-schema")},t.getMigrationState=function(){throw Et("migration-schema")},t.startMigration=function(e){return void 0===e&&(e=10),yr(this),this.getMigrationState().startMigration(e)},t.migratePromise=function(e){return void 0===e&&(e=10),this.getMigrationState().migratePromise(e)},t.insert=async function(e){yr(this);var t=await this.bulkInsert([e]),r=t.error[0];return Ge(this,e[this.schema.primaryPath],e,r),(0,ve.ZN)(t.success[0])},t.insertIfNotExists=async function(e){var t=await this.bulkInsert([e]);if(t.error.length>0){var r=t.error[0];if(409===r.status){var a=r.documentInDb;return Xt(this._docCache,[a])[0]}throw r}return t.success[0]},t.bulkInsert=async function(e){if(yr(this),0===e.length)return{success:[],error:[]};var t,r=this.schema.primaryPath,a=new Set;if(this.hasHooks("pre","insert"))t=await Promise.all(e.map((e=>{var t=pr(this.schema,e);return this._runHooks("pre","insert",t).then((()=>(a.add(t[r]),{document:t})))})));else{t=new Array(e.length);for(var n=this.schema,i=0;i{var t=e.document;l.set(t[r],t)})),await Promise.all(h.success.map((e=>this._runHooks("post","insert",l.get(e.primary),e))))}return h},t.bulkRemove=async function(e){yr(this);var t,r=this.schema.primaryPath;if(0===e.length)return{success:[],error:[]};"string"==typeof e[0]?t=await this.findByIds(e).exec():(t=new Map,e.forEach((e=>t.set(e.primary,e))));var a=[],n=new Map;Array.from(t.values()).forEach((e=>{var t=e.toMutableJSON(!0);a.push(t),n.set(e.primary,t)})),await Promise.all(a.map((e=>{var r=e[this.schema.primaryPath];return this._runHooks("pre","remove",e,t.get(r))})));var i=a.map((e=>{var t=s(e);return t._deleted=!0,{previous:e,document:t}})),o=await this.storageInstance.bulkWrite(i,"rx-collection-bulk-remove"),c=it(this.schema.primaryPath,i,o),u=[],h=c.map((e=>{var t=e[r],a=this._docCache.getCachedRxDocument(e);return u.push(a),t}));return await Promise.all(h.map((e=>this._runHooks("post","remove",n.get(e),t.get(e))))),{success:u,error:o.error}},t.bulkUpsert=async function(e){yr(this);var t=[],r=new Map;e.forEach((e=>{var a=pr(this.schema,e),n=a[this.schema.primaryPath];if(!n)throw S("COL3",{primaryPath:this.schema.primaryPath,data:a,schema:this.schema.jsonSchema});r.set(n,a),t.push(a)}));var a=await this.bulkInsert(t),i=a.success.slice(0),s=[];return await Promise.all(a.error.map((async e=>{if(409!==e.status)s.push(e);else{var t=e.documentId,a=n(r,t),o=(0,ve.ZN)(e.documentInDb),c=this._docCache.getCachedRxDocuments([o])[0],u=await c.incrementalModify((()=>a));i.push(u)}}))),{error:s,success:i}},t.upsert=async function(e){yr(this);var t=await this.bulkUpsert([e]);return Ge(this.asRxCollection,e[this.schema.primaryPath],e,t.error[0]),t.success[0]},t.incrementalUpsert=function(e){yr(this);var t=pr(this.schema,e),r=t[this.schema.primaryPath];if(!r)throw S("COL4",{data:e});var a=this._incrementalUpsertQueues.get(r);return a||(a=de.em),a=a.then((()=>function(e,t,r){var a=e._docCache.getLatestDocumentDataIfExists(t);if(a)return Promise.resolve({doc:e._docCache.getCachedRxDocuments([a])[0],inserted:!1});return e.findOne(t).exec().then((t=>t?{doc:t,inserted:!1}:e.insert(r).then((e=>({doc:e,inserted:!0})))))}(this,r,t))).then((e=>e.inserted?e.doc:function(e,t){return e.incrementalModify((e=>t))}(e.doc,t))),this._incrementalUpsertQueues.set(r,a),a},t.find=function(e){return yr(this),Ze("prePrepareRxQuery",{op:"find",queryObj:e,collection:this}),e||(e={selector:{}}),nr("find",e,this)},t.findOne=function(e){var t;if(yr(this),Ze("prePrepareRxQuery",{op:"findOne",queryObj:e,collection:this}),"string"==typeof e)t=nr("findOne",{selector:{[this.schema.primaryPath]:e},limit:1},this);else{if(e||(e={selector:{}}),e.limit)throw S("QU6");(e=s(e)).limit=1,t=nr("findOne",e,this)}return t},t.count=function(e){return yr(this),e||(e={selector:{}}),nr("count",e,this)},t.findByIds=function(e){return yr(this),nr("findByIds",{selector:{[this.schema.primaryPath]:{$in:e.slice(0)}}},this)},t.exportJSON=function(){throw Et("json-dump")},t.importJSON=function(e){throw Et("json-dump")},t.insertCRDT=function(e){throw Et("crdt")},t.addPipeline=function(e){throw Et("pipeline")},t.addHook=function(e,t,r,a){if(void 0===a&&(a=!1),"function"!=typeof r)throw j("COL7",{key:t,when:e});if(!kr.includes(e))throw j("COL8",{key:t,when:e});if(!_r.includes(t))throw S("COL9",{key:t});if("post"===e&&"create"===t&&!0===a)throw S("COL10",{when:e,key:t,parallel:a});var n=r.bind(this),i=a?"parallel":"series";this.hooks[t]=this.hooks[t]||{},this.hooks[t][e]=this.hooks[t][e]||{series:[],parallel:[]},this.hooks[t][e][i].push(n)},t.getHooks=function(e,t){return this.hooks[t]&&this.hooks[t][e]?this.hooks[t][e]:{series:[],parallel:[]}},t.hasHooks=function(e,t){if(!this.hooks[t]||!this.hooks[t][e])return!1;var r=this.getHooks(e,t);return!!r&&(r.series.length>0||r.parallel.length>0)},t._runHooks=function(e,t,r,a){var n=this.getHooks(e,t);if(!n)return de.em;var i=n.series.map((e=>()=>e(r,a)));return(0,de.h$)(i).then((()=>Promise.all(n.parallel.map((e=>e(r,a))))))},t._runHooksSync=function(e,t,r,a){if(this.hasHooks(e,t)){var n=this.getHooks(e,t);n&&n.series.forEach((e=>e(r,a)))}},t.promiseWait=function(e){return new Promise((t=>{var r=setTimeout((()=>{this.timeouts.delete(r),t()}),e);this.timeouts.add(r)}))},t.close=async function(){return this.closed?de.Dr:(Er.delete(this),await Promise.all(this.onClose.map((e=>e()))),this.closed=!0,Array.from(this.timeouts).forEach((e=>clearTimeout(e))),this._changeEventBuffer&&this._changeEventBuffer.close(),this.database.requestIdlePromise().then((()=>this.storageInstance.close())).then((()=>(this._subs.forEach((e=>e.unsubscribe())),delete this.database.collections[this.name],Ue("postCloseRxCollection",this).then((()=>!0))))))},t.remove=async function(){await this.close(),await Promise.all(this.onRemove.map((e=>e()))),await vr(this.database.storage,this.database.internalStore,this.database.token,this.database.name,this.name,this.database.multiInstance,this.database.password,this.database.hashFunction)},(0,x.A)(e,[{key:"insert$",get:function(){return this.$.pipe((0,xt.p)((e=>"INSERT"===e.operation)))}},{key:"update$",get:function(){return this.$.pipe((0,xt.p)((e=>"UPDATE"===e.operation)))}},{key:"remove$",get:function(){return this.$.pipe((0,xt.p)((e=>"DELETE"===e.operation)))}},{key:"asRxCollection",get:function(){return this}}])}();var Cr=r(7635),Or=r(5525),Pr=new Set,Sr=function(){function e(e,t,r,a,n,i,s,o,c,u,h,l,d){void 0===s&&(s=!1),void 0===o&&(o={}),this.idleQueue=new Cr.G,this.rxdbVersion=vt,this.storageInstances=new Set,this._subs=[],this.startupErrors=[],this.onClose=[],this.closed=!1,this.collections={},this.states={},this.eventBulks$=new oe.B,this.observable$=this.eventBulks$.pipe((0,Tt.Z)((e=>Pt(e)))),this.storageToken=de.Dr,this.storageTokenDocument=de.Dr,this.emittedEventBulkIds=new Or.p4(6e4),this.name=e,this.token=t,this.storage=r,this.instanceCreationOptions=a,this.password=n,this.multiInstance=i,this.eventReduce=s,this.options=o,this.internalStore=c,this.hashFunction=u,this.cleanupPolicy=h,this.allowSlowCount=l,this.reactivity=d,"pseudoInstance"!==this.name&&(this.internalStore=rt(this.asRxDatabase,c,ur),this.storageTokenDocument=async function(e){var t=(0,M.zs)(10),r=e.password?await e.hashFunction(JSON.stringify(e.password)):void 0,a=[{document:{id:mr,context:cr,key:dr,data:{rxdbVersion:e.rxdbVersion,token:t,instanceToken:e.token,passwordHash:r},_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}}}],n=await e.internalStore.bulkWrite(a,"internal-add-storage-token");if(!n.error[0])return it("id",a,n)[0];var i=(0,ve.ZN)(n.error[0]);if(i.isError&&$(i)){var s=i;if(!function(e,t){if(!e)return!1;var r=e.split(".")[0],a=t.split(".")[0];return"15"===r&&"16"===a||r===a}(s.documentInDb.data.rxdbVersion,e.rxdbVersion))throw S("DM5",{args:{database:e.name,databaseStateVersion:s.documentInDb.data.rxdbVersion,codeVersion:e.rxdbVersion}});if(r&&r!==s.documentInDb.data.passwordHash)throw S("DB1",{passwordHash:r,existingPasswordHash:s.documentInDb.data.passwordHash});var o=s.documentInDb;return(0,ve.ZN)(o)}throw i}(this.asRxDatabase).catch((e=>this.startupErrors.push(e))),this.storageToken=this.storageTokenDocument.then((e=>e.data.token)).catch((e=>this.startupErrors.push(e))))}var t=e.prototype;return t.getReactivityFactory=function(){if(!this.reactivity)throw S("DB14",{database:this.name});return this.reactivity},t.$emit=function(e){this.emittedEventBulkIds.has(e.id)||(this.emittedEventBulkIds.add(e.id),this.eventBulks$.next(e))},t.removeCollectionDoc=async function(e,t){var r=await Je(this.internalStore,hr(fr(e,t),or));if(!r)throw S("SNH",{name:e,schema:t});var a=tt(r);a._deleted=!0,await this.internalStore.bulkWrite([{document:a,previous:r}],"rx-database-remove-collection")},t.addCollections=async function(e){var t={},r={},a=[],n={};await Promise.all(Object.entries(e).map((async e=>{let[i,o]=e;var c=i,u=o.schema;t[c]=u;var h=wt(u,this.hashFunction);if(r[c]=h,this.collections[i])throw S("DB3",{name:i});var l=fr(i,u),d={id:hr(l,or),key:l,context:or,data:{name:c,schemaHash:await h.hash,schema:h.jsonSchema,version:h.version,connectedStorages:[]},_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}};a.push({document:d});var m=Object.assign({},o,{name:c,schema:h,database:this}),f=s(o);f.database=this,f.name=i,Ze("preCreateRxCollection",f),m.conflictHandler=f.conflictHandler,n[c]=m})));var i=await this.internalStore.bulkWrite(a,"rx-database-add-collection");await async function(e){if(await e.storageToken,e.startupErrors[0])throw e.startupErrors[0]}(this),await Promise.all(i.error.map((async e=>{if(409!==e.status)throw S("DB12",{database:this.name,writeError:e});var a=(0,ve.ZN)(e.documentInDb),n=a.data.name,i=r[n];if(a.data.schemaHash!==await i.hash)throw S("DB6",{database:this.name,collection:n,previousSchemaHash:a.data.schemaHash,schemaHash:await i.hash,previousSchema:a.data.schema,schema:(0,ve.ZN)(t[n])})})));var o={};return await Promise.all(Object.keys(e).map((async e=>{var t=n[e],r=await function(e){let{database:t,name:r,schema:a,instanceCreationOptions:n={},migrationStrategies:i={},autoMigrate:s=!0,statics:o={},methods:c={},attachments:u={},options:h={},localDocuments:l=!1,cacheReplacementPolicy:d=Vt,conflictHandler:m=xr}=e;var f={databaseInstanceToken:t.token,databaseName:t.name,collectionName:r,schema:a.jsonSchema,options:n,multiInstance:t.multiInstance,password:t.password,devMode:I.isDevMode()};return Ze("preCreateRxStorageInstance",f),async function(e,t){return t.multiInstance=e.multiInstance,await e.storage.createStorageInstance(t)}(t,f).then((e=>{var f=new Rr(t,r,a,e,n,i,c,u,h,d,o,m);return f.prepare().then((()=>{Object.entries(o).forEach((e=>{let[t,r]=e;Object.defineProperty(f,t,{get:()=>r.bind(f)})}));var e=de.em;return s&&0!==f.schema.version&&(e=f.migratePromise()),e})).then((()=>(Ze("createRxCollection",{collection:f,creator:{name:r,schema:a,storageInstance:e,instanceCreationOptions:n,migrationStrategies:i,methods:c,attachments:u,options:h,cacheReplacementPolicy:d,localDocuments:l,statics:o}}),f))).catch((t=>(Er.delete(f),e.close().then((()=>Promise.reject(t))))))}))}(t);o[e]=r,this.collections[e]=r,this[e]||Object.defineProperty(this,e,{get:()=>this.collections[e]})}))),o},t.lockedRun=function(e){return this.idleQueue.wrapCall(e)},t.requestIdlePromise=function(){return this.idleQueue.requestIdlePromise()},t.exportJSON=function(e){throw Et("json-dump")},t.addState=function(e){throw Et("state")},t.importJSON=function(e){throw Et("json-dump")},t.backup=function(e){throw Et("backup")},t.leaderElector=function(){throw Et("leader-election")},t.isLeader=function(){throw Et("leader-election")},t.waitForLeadership=function(){throw Et("leader-election")},t.migrationStates=function(){throw Et("migration-schema")},t.close=async function(){return this.closed?de.Dr:(this.closed=!0,await Ue("preCloseRxDatabase",this),this.eventBulks$.complete(),this._subs.map((e=>e.unsubscribe())),"pseudoInstance"===this.name?de.Dr:this.requestIdlePromise().then((()=>Promise.all(this.onClose.map((e=>e()))))).then((()=>Promise.all(Object.keys(this.collections).map((e=>this.collections[e])).map((e=>e.close()))))).then((()=>this.internalStore.close())).then((()=>Pr.delete(this.storage.name+"|"+this.name))).then((()=>!0)))},t.remove=function(){return this.close().then((()=>async function(e,t,r,a){void 0===r&&(r=!0);var n=(0,M.zs)(10),i=await jr(n,t,e,{},r,a),s=await lr(i),o=new Set;s.forEach((e=>o.add(e.data.name)));var c=Array.from(o);return await Promise.all(c.map((s=>vr(t,i,n,e,s,r,a)))),await Ue("postRemoveRxDatabase",{databaseName:e,storage:t}),await i.remove(),c}(this.name,this.storage,this.multiInstance,this.password)))},(0,x.A)(e,[{key:"$",get:function(){return this.observable$}},{key:"asRxDatabase",get:function(){return this}}])}();async function jr(e,t,r,a,n,i){return await t.createStorageInstance({databaseInstanceToken:e,databaseName:r,collectionName:Ve,schema:ur,options:a,multiInstance:n,password:i,devMode:I.isDevMode()})}function $r(e){let{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i=!0,eventReduce:s=!0,ignoreDuplicate:o=!1,options:c={},cleanupPolicy:u,allowSlowCount:h=!1,localDocuments:l=!1,hashFunction:d=le.V0,reactivity:m}=e;if(Ze("preCreateRxDatabase",{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i,eventReduce:s,ignoreDuplicate:o,options:c,localDocuments:l}),o){if(!I.isDevMode())throw S("DB9",{database:a})}else!function(e,t){var r=t.name+"|"+e;if(Pr.has(r))throw S("DB8",{name:e,storage:t.name,link:"https://rxdb.info/rx-database.html#ignoreduplicate"})}(a,t);Pr.add(t.name+"|"+a);var f=(0,M.zs)(10);return jr(f,t,a,r,i,n).catch((e=>{throw Pr.delete(t.name+"|"+a),e})).then((e=>{var p=new Sr(a,f,t,r,n,i,s,c,e,d,u,h,m);return Ue("createRxDatabase",{database:p,creator:{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i,eventReduce:s,ignoreDuplicate:o,options:c,localDocuments:l}}).then((()=>p))}))}var Nr={RxSchema:bt.prototype,RxDocument:$t,RxQuery:ar.prototype,RxCollection:Rr.prototype,RxDatabase:Sr.prototype},Ar=new Set,Br=new Set;var Mr=function(e){function t(t,r,a){var n;return(n=e.call(this,null,r)||this).id=t,n.parent=a,n}return(0,k.A)(t,e),t}(Nt()),qr={get isLocal(){return!0},get allAttachments$(){throw S("LD1",{document:this})},get primaryPath(){return"id"},get primary(){return this.id},get $(){var e=n(Wr,this.parent),t=this.primary;return this.parent.eventBulks$.pipe((0,xt.p)((e=>!!e.isLocal)),(0,Dt.T)((e=>e.events.find((e=>e.documentId===t)))),(0,xt.p)((e=>!!e)),(0,Dt.T)((e=>Rt((0,ve.ZN)(e)))),(0,kt.Z)(e.docCache.getLatestDocumentData(this.primary)),(0,_t.F)(((e,t)=>e._rev===t._rev)),(0,Dt.T)((t=>e.docCache.getCachedRxDocument(t))),(0,It.t)(ve.bz))},get $$(){var e=this,t=Qr(e);return t.getReactivityFactory().fromObservable(e.$,e.getLatest()._data,t)},get deleted$$(){var e=this,t=Qr(e);return t.getReactivityFactory().fromObservable(e.deleted$,e.getLatest().deleted,t)},getLatest(){var e=n(Wr,this.parent),t=e.docCache.getLatestDocumentData(this.primary);return e.docCache.getCachedRxDocument(t)},get(e){if(e="data."+e,this._data){if("string"!=typeof e)throw j("LD2",{objPath:e});var t=v(this._data,e);return t=I.deepFreezeWhenDevMode(t)}},get$(e){if(e="data."+e,I.isDevMode()){if(e.includes(".item."))throw S("LD3",{objPath:e});if(e===this.primaryPath)throw S("LD4")}return this.$.pipe((0,Dt.T)((e=>e._data)),(0,Dt.T)((t=>v(t,e))),(0,_t.F)())},get$$(e){var t=Qr(this);return t.getReactivityFactory().fromObservable(this.get$(e),this.getLatest().get(e),t)},async incrementalModify(e){var t=await Kr(this.parent);return t.incrementalWriteQueue.addWrite(this._data,(async t=>(t.data=await e(t.data,this),t))).then((e=>t.docCache.getCachedRxDocument(e)))},incrementalPatch(e){return this.incrementalModify((t=>(Object.entries(e).forEach((e=>{let[r,a]=e;t[r]=a})),t)))},async _saveData(e){var t=await Kr(this.parent),r=this._data;e.id=this.id;var a=[{previous:r,document:e}];return t.storageInstance.bulkWrite(a,"local-document-save-data").then((t=>{if(t.error[0])throw t.error[0];var r=it(this.collection.schema.primaryPath,a,t)[0];(e=s(e))._rev=r._rev}))},async remove(){var e=await Kr(this.parent),t=s(this._data);return t._deleted=!0,Ye(e.storageInstance,{previous:this._data,document:t},"local-document-remove").then((t=>e.docCache.getCachedRxDocument(t)))}},Tr=!1,Lr=()=>{if(!Tr){Tr=!0;var e=$t;Object.getOwnPropertyNames(e).forEach((t=>{if(!Object.getOwnPropertyDescriptor(qr,t)){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(qr,t,r)}}));["populate","update","putAttachment","getAttachment","allAttachments"].forEach((e=>qr[e]=(e=>()=>{throw S("LD6",{functionName:e})})(e)))}};function Qr(e){var t=e.parent;return t instanceof Sr?t:t.database}var Fr=new WeakMap,Wr=new WeakMap;function Hr(e){var t=e.database?e.database:e,r=e.database?e.name:"",a=(async()=>{var a=await zr(t.token,t.storage,t.name,r,t.instanceCreationOptions,t.multiInstance);a=rt(t,a,Jr);var n=new Yt("id",t.eventBulks$.pipe((0,xt.p)((e=>{var t=!1;return(""===r&&!e.collectionName||""!==r&&e.collectionName===r)&&(t=!0),t&&e.isLocal})),(0,Dt.T)((e=>e.events))),(t=>function(e,t){Lr();var r=new Mr(e.id,e,t);return Object.setPrototypeOf(r,qr),r.prototype=qr,r}(t,e))),i=new St(a,"id",(()=>{}),(()=>{})),s=await t.storageToken,o=a.changeStream().subscribe((r=>{for(var a=new Array(r.events.length),n=r.events,i=e.database?e.name:void 0,o=0;oe.storageInstance.close()))}async function Ur(e,t,r){var a=(0,M.zs)(10),n=await zr(a,e,t,r,{},!1);await n.remove()}function Vr(e){return"plugin-local-documents-"+e}var Jr=Q({title:"RxLocalDocument",version:0,primaryKey:"id",type:"object",properties:{id:{type:"string",maxLength:128},data:{type:"object",additionalProperties:!0}},required:["id","data"]});async function Yr(e,t){var r=await Kr(this),a={id:e,data:t,_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}};return Ye(r.storageInstance,{document:a},"local-document-insert").then((e=>r.docCache.getCachedRxDocument(e)))}function Gr(e,t){return this.getLocal(e).then((r=>r?r.incrementalModify((()=>t)):this.insertLocal(e,t)))}async function Xr(e){var t=await Kr(this),r=t.docCache,a=r.getLatestDocumentDataIfExists(e);return a?Promise.resolve(r.getCachedRxDocument(a)):Je(t.storageInstance,e).then((e=>e?t.docCache.getCachedRxDocument(e):null))}function ea(e){return this.$.pipe((0,kt.Z)(null),(0,Tt.Z)((async t=>t?{changeEvent:t}:{doc:await this.getLocal(e)})),(0,Tt.Z)((async t=>{if(t.changeEvent){var r=t.changeEvent;return r.isLocal&&r.documentId===e?{use:!0,doc:await this.getLocal(e)}:{use:!1}}return{use:!0,doc:t.doc}})),(0,xt.p)((e=>e.use)),(0,Dt.T)((e=>e.doc)))}var ta={name:"local-documents",rxdb:!0,prototypes:{RxCollection:e=>{e.insertLocal=Yr,e.upsertLocal=Gr,e.getLocal=Xr,e.getLocal$=ea},RxDatabase:e=>{e.insertLocal=Yr,e.upsertLocal=Gr,e.getLocal=Xr,e.getLocal$=ea}},hooks:{createRxDatabase:{before:e=>{e.creator.localDocuments&&Hr(e.database)}},createRxCollection:{before:e=>{e.creator.localDocuments&&Hr(e.collection)}},preCloseRxDatabase:{after:e=>Zr(e)},postCloseRxCollection:{after:e=>Zr(e)},postRemoveRxDatabase:{after:e=>Ur(e.storage,e.databaseName,"")},postRemoveRxCollection:{after:e=>Ur(e.storage,e.databaseName,e.collectionName)}},overwritable:{}};let ra;function aa(){return"undefined"!=typeof window&&window.indexedDB}function na(){return ra||(ra=(async()=>{!function(e){if(Ze("preAddRxPlugin",{plugin:e,plugins:Ar}),!Ar.has(e)){if(Br.has(e.name))throw S("PL3",{name:e.name,plugin:e});if(Ar.add(e),Br.add(e.name),!e.rxdb)throw j("PL1",{plugin:e});e.init&&e.init(),e.prototypes&&Object.entries(e.prototypes).forEach((e=>{let[t,r]=e;return r(Nr[t])})),e.overwritable&&Object.assign(I,e.overwritable),e.hooks&&Object.entries(e.hooks).forEach((e=>{let[t,r]=e;r.after&&ze[t].push(r.after),r.before&&ze[t].unshift(r.before)}))}}(ta);var e;return await $r({name:"rxdb-landing-v4",localDocuments:!0,storage:(void 0===e&&(e={}),new yt(e))})})()),ra}},7587:(e,t,r)=>{r.d(t,{L$:()=>s,Z2:()=>i,zs:()=>n});var a="abcdefghijklmnopqrstuvwxyz";function n(e){void 0===e&&(e=10);for(var t="",r=0;r{function a(){return new Promise((e=>setTimeout(e,0)))}function n(e){return void 0===e&&(e=0),new Promise((t=>setTimeout(t,e)))}r.d(t,{$A:()=>s,Dr:()=>i,ND:()=>n,Ve:()=>h,dY:()=>a,em:()=>o,h$:()=>l,vN:()=>c});Promise.resolve(!0);var i=Promise.resolve(!1),s=Promise.resolve(null),o=Promise.resolve();function c(e){return void 0===e&&(e=1e4),"function"==typeof requestIdleCallback?new Promise((t=>{requestIdleCallback((()=>t()),{timeout:e})})):n(0)}var u=o;function h(e){return void 0===e&&(e=void 0),u=u.then((()=>c(e)))}function l(e,t){return e.reduce(((e,t)=>e.then(t)),Promise.resolve(t))}}}]); \ No newline at end of file diff --git a/docs/assets/js/380cc66a.72c2626d.js b/docs/assets/js/380cc66a.72c2626d.js deleted file mode 100644 index 323f1942b33..00000000000 --- a/docs/assets/js/380cc66a.72c2626d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2061],{1772:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"rx-storage-dexie","title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes.","source":"@site/docs/rx-storage-dexie.md","sourceDirName":".","slug":"/rx-storage-dexie.html","permalink":"/rx-storage-dexie.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","slug":"rx-storage-dexie.html","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes."},"sidebar":"tutorialSidebar","previous":{"title":"RxStorage Overview","permalink":"/rx-storage.html"},"next":{"title":"IndexedDB \ud83d\udc51","permalink":"/rx-storage-indexeddb.html"}}');var t=n(4848),i=n(8453);const o={title:"Lightning-Fast Browser DB - RxDB Dexie RxStorage",slug:"rx-storage-dexie.html",description:"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes."},a="RxStorage Dexie.js",d={},l=[{value:"Usage",id:"usage",level:2},{value:"Overwrite/Polyfill the native IndexedDB",id:"overwritepolyfill-the-native-indexeddb",level:2},{value:"Using addons",id:"using-addons",level:2},{value:"Disabling the non-premium console log",id:"disabling-the-non-premium-console-log",level:2},{value:"Performance comparison with other RxStorage plugins",id:"performance-comparison-with-other-rxstorage-plugins",level:2}];function x(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"rxstorage-dexiejs",children:"RxStorage Dexie.js"})}),"\n",(0,t.jsxs)(r.p,{children:["To store the data inside of IndexedDB in the browser, you can use the ",(0,t.jsx)(r.a,{href:"https://github.com/dexie/Dexie.js",children:"Dexie.js"})," ",(0,t.jsx)(r.a,{href:"/rx-storage.html",children:"RxStorage"}),". Dexie.js is a minimal wrapper around IndexedDB and the Dexie.js RxStorage wraps that again to store RxDB data in the browser. For side projects and prototypes that run in a browser, you should use the dexie RxStorage as a default."]}),"\n",(0,t.jsxs)(r.admonition,{type:"note",children:[(0,t.jsxs)(r.p,{children:["While Dexie.js RxStorage can be used for free, most professional projects should switch to our ",(0,t.jsxs)(r.strong,{children:["premium ",(0,t.jsx)(r.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB RxStorage"})," \ud83d\udc51"]})," in production:"]}),(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["It is faster and reduces build size by up to ",(0,t.jsx)(r.strong,{children:"36%"}),"."]}),"\n",(0,t.jsxs)(r.li,{children:["It has a way ",(0,t.jsx)(r.a,{href:"/rx-storage-performance.html",children:"better performance"})," on reads and writes."]}),"\n",(0,t.jsxs)(r.li,{children:["It does not use a ",(0,t.jsx)(r.a,{href:"/slow-indexeddb.html#batched-cursor",children:"Batched Cursor"})," or ",(0,t.jsx)(r.a,{href:"/slow-indexeddb.html#custom-indexes",children:"custom indexes"})," which makes queries slower compared to the ",(0,t.jsx)(r.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB RxStorage"}),"."]}),"\n",(0,t.jsxs)(r.li,{children:["It supports ",(0,t.jsx)(r.strong,{children:"non-required indexes"})," which is ",(0,t.jsx)(r.a,{href:"https://github.com/pubkey/rxdb/pull/6643#issuecomment-2505310082",children:"not possible"})," with Dexie.js."]}),"\n",(0,t.jsxs)(r.li,{children:["It runs in a ",(0,t.jsx)(r.strong,{children:"WAL-like mode"})," (similar to SQLite) for faster writes and improved responsiveness."]}),"\n",(0,t.jsxs)(r.li,{children:["It support the ",(0,t.jsx)(r.a,{href:"/rx-storage-indexeddb.html#storage-buckets",children:"Storage Buckets API"})]}),"\n"]})]}),"\n",(0,t.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie()\n});\n"})}),"\n",(0,t.jsx)(r.h2,{id:"overwritepolyfill-the-native-indexeddb",children:"Overwrite/Polyfill the native IndexedDB"}),"\n",(0,t.jsxs)(r.p,{children:["Node.js has no IndexedDB API. To still run the Dexie ",(0,t.jsx)(r.code,{children:"RxStorage"})," in Node.js, for example to run unit tests, you have to polyfill it.\nYou can do that by using the ",(0,t.jsx)(r.a,{href:"https://github.com/dumbmatter/fakeIndexedDB",children:"fake-indexeddb"})," module and pass it to the ",(0,t.jsx)(r.code,{children:"getRxStorageDexie()"})," function."]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\n//> npm install fake-indexeddb --save\nconst fakeIndexedDB = require('fake-indexeddb');\nconst fakeIDBKeyRange = require('fake-indexeddb/lib/FDBKeyRange');\n\nconst db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie({\n indexedDB: fakeIndexedDB,\n IDBKeyRange: fakeIDBKeyRange\n })\n});\n\n"})}),"\n",(0,t.jsx)(r.h2,{id:"using-addons",children:"Using addons"}),"\n",(0,t.jsxs)(r.p,{children:["Dexie.js has its own plugin system with ",(0,t.jsx)(r.a,{href:"https://dexie.org/docs/DerivedWork#known-addons",children:"many plugins"})," for encryption, replication or other use cases. With the Dexie.js ",(0,t.jsx)(r.code,{children:"RxStorage"})," you can use the same plugins by passing them to the ",(0,t.jsx)(r.code,{children:"getRxStorageDexie()"})," function."]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",children:"const db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie({\n addons: [ /* Your Dexie.js plugins */ ]\n })\n});\n"})}),"\n",(0,t.jsx)(r.h2,{id:"disabling-the-non-premium-console-log",children:"Disabling the non-premium console log"}),"\n",(0,t.jsxs)(r.p,{children:["We want to be transparent with our community, and you'll notice a console message when using the free Dexie.js based RxStorage implementation. This message serves to inform you about the availability of faster storage solutions within our ",(0,t.jsx)(r.a,{href:"/premium/",children:"\ud83d\udc51 Premium Plugins"}),". We understand that this might be a minor inconvenience, and we sincerely apologize for that. However, maintaining and improving RxDB requires substantial resources, and our premium users help us ensure its sustainability. If you find value in RxDB and wish to remove this message, we encourage you to explore our premium storage options, which are optimized for professional use and production environments. Thank you for your understanding and support."]}),"\n",(0,t.jsxs)(r.p,{children:["If you already have premium access and want to use the Dexie.js ",(0,t.jsx)(r.a,{href:"/rx-storage.html",children:"RxStorage"})," without the log, you can call the ",(0,t.jsx)(r.code,{children:"setPremiumFlag()"})," function to disable the log."]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",children:"import { setPremiumFlag } from 'rxdb-premium/plugins/shared';\nsetPremiumFlag();\n"})}),"\n",(0,t.jsx)(r.h2,{id:"performance-comparison-with-other-rxstorage-plugins",children:"Performance comparison with other RxStorage plugins"}),"\n",(0,t.jsx)(r.p,{children:"The performance of the Dexie.js RxStorage is good enough for most use cases but other storages can have way better performance metrics:"}),"\n",(0,t.jsx)("p",{align:"center",children:(0,t.jsx)("img",{src:"./files/rx-storage-performance-browser.png",alt:"RxStorage performance - browser Dexie.js",width:"700"})})]})}function h(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(x,{...e})}):x(e)}},8453:(e,r,n)=>{n.d(r,{R:()=>o,x:()=>a});var s=n(6540);const t={},i=s.createContext(t);function o(e){const r=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/380cc66a.816f4a8f.js b/docs/assets/js/380cc66a.816f4a8f.js new file mode 100644 index 00000000000..6f067351a18 --- /dev/null +++ b/docs/assets/js/380cc66a.816f4a8f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2061],{1772:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>d,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>x});const s=JSON.parse('{"id":"rx-storage-dexie","title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes.","source":"@site/docs/rx-storage-dexie.md","sourceDirName":".","slug":"/rx-storage-dexie.html","permalink":"/rx-storage-dexie.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Lightning-Fast Browser DB - RxDB Dexie RxStorage","slug":"rx-storage-dexie.html","description":"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes."},"sidebar":"tutorialSidebar","previous":{"title":"RxStorage Overview","permalink":"/rx-storage.html"},"next":{"title":"IndexedDB \ud83d\udc51","permalink":"/rx-storage-indexeddb.html"}}');var n=t(4848),i=t(8453),o=t(7580);const a={title:"Lightning-Fast Browser DB - RxDB Dexie RxStorage",slug:"rx-storage-dexie.html",description:"Use Dexie.js to power RxDB in the browser. Enjoy quick setup, Dexie addons, and reliable storage for small apps or prototypes."},d="RxStorage Dexie.js",l={},x=[{value:"Usage",id:"usage",level:2},{value:"Import the Dexie Storage",id:"import-the-dexie-storage",level:2},{value:"Create a Database",id:"create-a-database",level:2},{value:"Overwrite/Polyfill the native IndexedDB",id:"overwritepolyfill-the-native-indexeddb",level:2},{value:"Using addons",id:"using-addons",level:2},{value:"Disabling the non-premium console log",id:"disabling-the-non-premium-console-log",level:2},{value:"Performance comparison with other RxStorage plugins",id:"performance-comparison-with-other-rxstorage-plugins",level:2}];function h(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.header,{children:(0,n.jsx)(r.h1,{id:"rxstorage-dexiejs",children:"RxStorage Dexie.js"})}),"\n",(0,n.jsxs)(r.p,{children:["To store the data inside of IndexedDB in the browser, you can use the ",(0,n.jsx)(r.a,{href:"https://github.com/dexie/Dexie.js",children:"Dexie.js"})," ",(0,n.jsx)(r.a,{href:"/rx-storage.html",children:"RxStorage"}),". Dexie.js is a minimal wrapper around IndexedDB and the Dexie.js RxStorage wraps that again to store RxDB data in the browser. For side projects and prototypes that run in a browser, you should use the dexie RxStorage as a default."]}),"\n",(0,n.jsxs)(r.admonition,{type:"note",children:[(0,n.jsxs)(r.p,{children:["While Dexie.js RxStorage can be used for free, most professional projects should switch to our ",(0,n.jsxs)(r.strong,{children:["premium ",(0,n.jsx)(r.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB RxStorage"})," \ud83d\udc51"]})," in production:"]}),(0,n.jsxs)(r.ul,{children:["\n",(0,n.jsxs)(r.li,{children:["It is faster and reduces build size by up to ",(0,n.jsx)(r.strong,{children:"36%"}),"."]}),"\n",(0,n.jsxs)(r.li,{children:["It has a way ",(0,n.jsx)(r.a,{href:"/rx-storage-performance.html",children:"better performance"})," on reads and writes."]}),"\n",(0,n.jsxs)(r.li,{children:["It does not use a ",(0,n.jsx)(r.a,{href:"/slow-indexeddb.html#batched-cursor",children:"Batched Cursor"})," or ",(0,n.jsx)(r.a,{href:"/slow-indexeddb.html#custom-indexes",children:"custom indexes"})," which makes queries slower compared to the ",(0,n.jsx)(r.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB RxStorage"}),"."]}),"\n",(0,n.jsxs)(r.li,{children:["It supports ",(0,n.jsx)(r.strong,{children:"non-required indexes"})," which is ",(0,n.jsx)(r.a,{href:"https://github.com/pubkey/rxdb/pull/6643#issuecomment-2505310082",children:"not possible"})," with Dexie.js."]}),"\n",(0,n.jsxs)(r.li,{children:["It runs in a ",(0,n.jsx)(r.strong,{children:"WAL-like mode"})," (similar to SQLite) for faster writes and improved responsiveness."]}),"\n",(0,n.jsxs)(r.li,{children:["It support the ",(0,n.jsx)(r.a,{href:"/rx-storage-indexeddb.html#storage-buckets",children:"Storage Buckets API"})]}),"\n"]})]}),"\n",(0,n.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsxs)(o.g,{children:[(0,n.jsx)(r.h2,{id:"import-the-dexie-storage",children:"Import the Dexie Storage"}),(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n"})}),(0,n.jsx)(r.h2,{id:"create-a-database",children:"Create a Database"}),(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-ts",children:"const db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie()\n});\n"})})]}),"\n",(0,n.jsx)(r.h2,{id:"overwritepolyfill-the-native-indexeddb",children:"Overwrite/Polyfill the native IndexedDB"}),"\n",(0,n.jsxs)(r.p,{children:["Node.js has no IndexedDB API. To still run the Dexie ",(0,n.jsx)(r.code,{children:"RxStorage"})," in Node.js, for example to run unit tests, you have to polyfill it.\nYou can do that by using the ",(0,n.jsx)(r.a,{href:"https://github.com/dumbmatter/fakeIndexedDB",children:"fake-indexeddb"})," module and pass it to the ",(0,n.jsx)(r.code,{children:"getRxStorageDexie()"})," function."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\n//> npm install fake-indexeddb --save\nconst fakeIndexedDB = require('fake-indexeddb');\nconst fakeIDBKeyRange = require('fake-indexeddb/lib/FDBKeyRange');\n\nconst db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie({\n indexedDB: fakeIndexedDB,\n IDBKeyRange: fakeIDBKeyRange\n })\n});\n\n"})}),"\n",(0,n.jsx)(r.h2,{id:"using-addons",children:"Using addons"}),"\n",(0,n.jsxs)(r.p,{children:["Dexie.js has its own plugin system with ",(0,n.jsx)(r.a,{href:"https://dexie.org/docs/DerivedWork#known-addons",children:"many plugins"})," for encryption, replication or other use cases. With the Dexie.js ",(0,n.jsx)(r.code,{children:"RxStorage"})," you can use the same plugins by passing them to the ",(0,n.jsx)(r.code,{children:"getRxStorageDexie()"})," function."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-ts",children:"const db = await createRxDatabase({\n name: 'exampledb',\n storage: getRxStorageDexie({\n addons: [ /* Your Dexie.js plugins */ ]\n })\n});\n"})}),"\n",(0,n.jsx)(r.h2,{id:"disabling-the-non-premium-console-log",children:"Disabling the non-premium console log"}),"\n",(0,n.jsxs)(r.p,{children:["We want to be transparent with our community, and you'll notice a console message when using the free Dexie.js based RxStorage implementation. This message serves to inform you about the availability of faster storage solutions within our ",(0,n.jsx)(r.a,{href:"/premium/",children:"\ud83d\udc51 Premium Plugins"}),". We understand that this might be a minor inconvenience, and we sincerely apologize for that. However, maintaining and improving RxDB requires substantial resources, and our premium users help us ensure its sustainability. If you find value in RxDB and wish to remove this message, we encourage you to explore our premium storage options, which are optimized for professional use and production environments. Thank you for your understanding and support."]}),"\n",(0,n.jsxs)(r.p,{children:["If you already have premium access and want to use the Dexie.js ",(0,n.jsx)(r.a,{href:"/rx-storage.html",children:"RxStorage"})," without the log, you can call the ",(0,n.jsx)(r.code,{children:"setPremiumFlag()"})," function to disable the log."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-js",children:"import { setPremiumFlag } from 'rxdb-premium/plugins/shared';\nsetPremiumFlag();\n"})}),"\n",(0,n.jsx)(r.h2,{id:"performance-comparison-with-other-rxstorage-plugins",children:"Performance comparison with other RxStorage plugins"}),"\n",(0,n.jsx)(r.p,{children:"The performance of the Dexie.js RxStorage is good enough for most use cases but other storages can have way better performance metrics:"}),"\n",(0,n.jsx)("p",{align:"center",children:(0,n.jsx)("img",{src:"./files/rx-storage-performance-browser.png",alt:"RxStorage performance - browser Dexie.js",width:"700"})})]})}function c(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},7580:(e,r,t)=>{t.d(r,{g:()=>n});var s=t(4848);function n(e){const r=[];let t=null;return e.children.forEach((e=>{e.props.id?(t&&r.push(t),t={headline:e,paragraphs:[]}):t&&t.paragraphs.push(e)})),t&&r.push(t),(0,s.jsx)("div",{style:i.stepsContainer,children:r.map(((e,r)=>(0,s.jsxs)("div",{style:i.stepWrapper,children:[(0,s.jsxs)("div",{style:i.stepIndicator,children:[(0,s.jsxs)("div",{style:i.stepNumber,children:[r+1,"."]}),(0,s.jsx)("div",{style:i.verticalLine})]}),(0,s.jsxs)("div",{style:i.stepContent,children:[(0,s.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,r)=>(0,s.jsx)("div",{style:i.item,children:e},r)))]})]},r)))})}const i={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,r,t)=>{t.d(r,{R:()=>o,x:()=>a});var s=t(6540);const n={},i=s.createContext(n);function o(e){const r=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/388.d17e0423.js b/docs/assets/js/388.ef8c28c5.js similarity index 57% rename from docs/assets/js/388.d17e0423.js rename to docs/assets/js/388.ef8c28c5.js index 4700f6241b6..330e0c93ca5 100644 --- a/docs/assets/js/388.d17e0423.js +++ b/docs/assets/js/388.ef8c28c5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[388],{388:(e,t,s)=>{s.r(t),s.d(t,{default:()=>h});s(6540);var i=s(539),n=s(1769),r=s(6442),l=s(7138),a=s(4848);function h(){const e=(0,i.T)({id:"theme.NotFound.title",message:"RxDB - 404 Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.be,{title:e}),(0,a.jsx)(r.A,{title:"RxDB - 404 Page Not Found",children:(0,a.jsx)(l.A,{})})]})}},7138:(e,t,s)=>{s.d(t,{A:()=>a});s(6540);var i=s(4164),n=s(539),r=s(9303),l=s(4848);function a(e){let{className:t}=e;return(0,l.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,l.jsx)("div",{className:"row",children:(0,l.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,l.jsxs)(r.A,{as:"h1",className:"hero__title",children:[(0,l.jsx)("a",{href:"/",children:(0,l.jsx)("div",{style:{textAlign:"center"},children:(0,l.jsx)("img",{src:"https://rxdb.info/files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"160"})})}),(0,l.jsx)(n.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"404 Page Not Found"})]}),(0,l.jsx)("p",{children:(0,l.jsx)(n.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it."})}),(0,l.jsx)("p",{children:"Maybe one of these can help you to find the desired content:"}),(0,l.jsx)("div",{className:"ul-container",children:(0,l.jsxs)("ul",{children:[(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"https://rxdb.info/quickstart.html",children:"RxDB Documentation"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"/chat/",children:"RxDB Discord Channel"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"https://twitter.com/intent/user?screen_name=rxdbjs",children:"RxDB on twitter"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"/code/",children:"RxDB at Github"})})]})})]})})})}}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[388],{388:(e,t,s)=>{s.r(t),s.d(t,{default:()=>a});s(6540);var i=s(539),n=s(1769),r=s(6442),l=s(7138),h=s(4848);function a(){const e=(0,i.T)({id:"theme.NotFound.title",message:"RxDB - 404 Page Not Found"});return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(n.be,{title:e}),(0,h.jsx)(r.A,{title:"RxDB - 404 Page Not Found",children:(0,h.jsx)(l.A,{})})]})}},7138:(e,t,s)=>{s.d(t,{A:()=>h});s(6540);var i=s(4164),n=s(539),r=s(9303),l=s(4848);function h(e){let{className:t}=e;return(0,l.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,l.jsx)("div",{className:"row",children:(0,l.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,l.jsxs)(r.A,{as:"h1",className:"hero__title",children:[(0,l.jsx)("a",{href:"/",children:(0,l.jsx)("div",{style:{textAlign:"center"},children:(0,l.jsx)("img",{src:"https://rxdb.info/files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"160"})})}),(0,l.jsx)(n.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"404 Page Not Found"})]}),(0,l.jsx)("p",{children:(0,l.jsx)(n.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it."})}),(0,l.jsx)("p",{children:"Maybe one of these can help you to find the desired content:"}),(0,l.jsx)("div",{className:"ul-container",children:(0,l.jsxs)("ul",{children:[(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"https://rxdb.info/overview.html",children:"RxDB Documentation"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"/chat/",children:"RxDB Discord Channel"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"https://twitter.com/intent/user?screen_name=rxdbjs",children:"RxDB on twitter"})}),(0,l.jsx)("li",{children:(0,l.jsx)("a",{href:"/code/",children:"RxDB at Github"})})]})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/7175.fc317e7f.js b/docs/assets/js/7175.fc317e7f.js new file mode 100644 index 00000000000..e141af7df13 --- /dev/null +++ b/docs/assets/js/7175.fc317e7f.js @@ -0,0 +1 @@ +(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[7175],{235:(e,t,n)=>{"use strict";n.d(t,{R0:()=>u,lI:()=>i});var r=n(1693);function o(e){return e[e.length-1]}function i(e){return(t=o(e))&&(0,r.T)(t.schedule)?e.pop():void 0;var t}function u(e,t){return"number"==typeof o(e)?e.pop():t}},374:(e,t,n)=>{"use strict";n.d(t,{dF:()=>o,xW:()=>i});var r=n(744);function o(e){return e instanceof a?e:new a(e)}function i(...e){let t=0;return o((()=>{for(;t{const e=n.next();if(e.done)throw s;return e.value}}else if((0,r.cy)(e)){const n=e,r=n.length;let o=0;t=()=>{if(o0?this.push(2,e):this}drop(e){return e>0?this.push(3,e):this}transform(e){const t=this;let n;return o((()=>(n||(n=o(e(t.value()))),n.next())))}value(){return this.isDone||(this.isDone=this.#n(!0).done),this.#t}each(e){for(;;){const t=this.next();if(t.done)break;if(!1===e(t.value))return!1}return!0}reduce(e,t){let n=this.next();for(void 0!==t||n.done||(t=n.value,n=this.next());!n.done;)t=e(t,n.value),n=this.next();return t}size(){return this.reduce(((e,t)=>++e),0)}[Symbol.iterator](){return this}}},703:(e,t,n)=>{"use strict";n.d(t,{X2:()=>I});Promise.resolve(!1),Promise.resolve(!0);var r=Promise.resolve();function o(e,t){return e||(e=0),new Promise((function(n){return setTimeout((function(){return n(t)}),e)}))}function i(){return Math.random().toString(36).substring(2)}var u=0;function s(){var e=1e3*Date.now();return e<=u&&(e=u+1),u=e,e}var a={create:function(e){var t={time:s(),messagesCallback:null,bc:new BroadcastChannel(e),subFns:[]};return t.bc.onmessage=function(e){t.messagesCallback&&t.messagesCallback(e.data)},t},close:function(e){e.bc.close(),e.subFns=[]},onMessage:function(e,t){e.messagesCallback=t},postMessage:function(e,t){try{return e.bc.postMessage(t,!1),r}catch(n){return Promise.reject(n)}},canBeUsed:function(){if("undefined"!=typeof globalThis&&globalThis.Deno&&globalThis.Deno.args)return!0;if("undefined"==typeof window&&"undefined"==typeof self||"function"!=typeof BroadcastChannel)return!1;if(BroadcastChannel._pubkey)throw new Error("BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill");return!0},type:"native",averageResponseTime:function(){return 150},microSeconds:s},c=n(5525);function l(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=JSON.parse(JSON.stringify(e));return void 0===t.webWorkerSupport&&(t.webWorkerSupport=!0),t.idb||(t.idb={}),t.idb.ttl||(t.idb.ttl=45e3),t.idb.fallbackInterval||(t.idb.fallbackInterval=150),e.idb&&"function"==typeof e.idb.onclose&&(t.idb.onclose=e.idb.onclose),t.localstorage||(t.localstorage={}),t.localstorage.removeTimeout||(t.localstorage.removeTimeout=6e4),e.methods&&(t.methods=e.methods),t.node||(t.node={}),t.node.ttl||(t.node.ttl=12e4),t.node.maxParallelWrites||(t.node.maxParallelWrites=2048),void 0===t.node.useFastPath&&(t.node.useFastPath=!0),t}var f="messages",h={durability:"relaxed"};function d(){if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof window){if(void 0!==window.mozIndexedDB)return window.mozIndexedDB;if(void 0!==window.webkitIndexedDB)return window.webkitIndexedDB;if(void 0!==window.msIndexedDB)return window.msIndexedDB}return!1}function p(e){e.commit&&e.commit()}function y(e,t){var n=e.transaction(f,"readonly",h),r=n.objectStore(f),o=[],i=IDBKeyRange.bound(t+1,1/0);if(r.getAll){var u=r.getAll(i);return new Promise((function(e,t){u.onerror=function(e){return t(e)},u.onsuccess=function(t){e(t.target.result)}}))}return new Promise((function(e,u){var s=function(){try{return i=IDBKeyRange.bound(t+1,1/0),r.openCursor(i)}catch(e){return r.openCursor()}}();s.onerror=function(e){return u(e)},s.onsuccess=function(r){var i=r.target.result;i?i.value.ide.lastCursorId&&(e.lastCursorId=t.id),t})).filter((function(t){return function(e,t){return!(e.uuid===t.uuid||t.eMIs.has(e.id)||e.data.time0||e._addEL.internal.length>0}function K(e,t,n){e._addEL[t].push(n),function(e){if(!e._iL&&T(e)){var t=function(t){e._addEL[t.type].forEach((function(e){t.time>=e.time&&e.fn(t.data)}))},n=e.method.microSeconds();e._prepP?e._prepP.then((function(){e._iL=!0,e.method.onMessage(e._state,t,n)})):(e._iL=!0,e.method.onMessage(e._state,t,n))}}(e)}function D(e,t,n){e._addEL[t]=e._addEL[t].filter((function(e){return e!==n})),function(e){if(e._iL&&!T(e)){e._iL=!1;var t=e.method.microSeconds();e.method.onMessage(e._state,null,t)}}(e)}I._pubkey=!0,I.prototype={postMessage:function(e){if(this.closed)throw new Error("BroadcastChannel.postMessage(): Cannot post message after channel has closed "+JSON.stringify(e));return M(this,"message",e)},postInternal:function(e){return M(this,"internal",e)},set onmessage(e){var t={time:this.method.microSeconds(),fn:e};D(this,"message",this._onML),e&&"function"==typeof e?(this._onML=t,K(this,"message",t)):this._onML=null},addEventListener:function(e,t){K(this,e,{time:this.method.microSeconds(),fn:t})},removeEventListener:function(e,t){D(this,e,this._addEL[e].find((function(e){return e.fn===t})))},close:function(){var e=this;if(!this.closed){j.delete(this),this.closed=!0;var t=this._prepP?this._prepP:r;return this._onML=null,this._addEL.message=[],t.then((function(){return Promise.all(Array.from(e._uMP))})).then((function(){return Promise.all(e._befC.map((function(e){return e()})))})).then((function(){return e.method.close(e._state)}))}},get type(){return this.method.type},get isClosed(){return this.closed}}},744:(e,t,n)=>{"use strict";n.d(t,{$P:()=>w,$z:()=>B,B2:()=>U,Bq:()=>T,E$:()=>M,Et:()=>v,Gv:()=>b,Im:()=>E,KY:()=>W,Kg:()=>y,Lm:()=>p,QP:()=>d,Rm:()=>L,S8:()=>Q,Tn:()=>x,UD:()=>l,Zo:()=>X,cy:()=>m,d8:()=>r,eC:()=>P,gD:()=>k,gd:()=>_,h1:()=>I,hd:()=>$,mg:()=>j,n4:()=>R,vA:()=>h,vN:()=>O,yT:()=>G,zy:()=>S});class r extends Error{}const o=Symbol("missing"),i=Object.freeze(new Error("mingo: cycle detected while processing object/array")),u=e=>{const t=q(e);let n=0,r=t.length;for(;r;)n=(n<<5)-n^t.charCodeAt(--r);return n>>>0},s=e=>"object"!=typeof e&&"function"!=typeof e||null===e,a=e=>s(e)||w(e)||_(e),c={undefined:1,null:2,number:3,string:4,symbol:5,object:6,array:7,arraybuffer:8,boolean:9,date:10,regexp:11,function:12},l=(e,t)=>{e===o&&(e=void 0),t===o&&(t=void 0);const[n,r]=[e,t].map((e=>c[d(e)]));return n!==r?n-r:R(e,t)?0:et?1:0};class f extends Map{#r=u;#o=new Map;#i=e=>{const t=this.#r(e);return[(this.#o.get(t)||[]).find((t=>R(t,e))),t]};constructor(){super()}static init(e){const t=new f;return e&&(t.#r=e),t}clear(){super.clear(),this.#o.clear()}delete(e){if(s(e))return super.delete(e);const[t,n]=this.#i(e);return!!super.delete(t)&&(this.#o.set(n,this.#o.get(n).filter((e=>!R(e,t)))),!0)}get(e){if(s(e))return super.get(e);const[t,n]=this.#i(e);return super.get(t)}has(e){if(s(e))return super.has(e);const[t,n]=this.#i(e);return super.has(t)}set(e,t){if(s(e))return super.set(e,t);const[n,r]=this.#i(e);if(super.has(n))super.set(n,t);else{super.set(e,t);const n=this.#o.get(r)||[];n.push(e),this.#o.set(r,n)}return this}get size(){return super.size}}function h(e,t){if(!e)throw new r(t)}const d=e=>{const t=Object.prototype.toString.call(e),n=t.substring(8,t.length-1).toLowerCase();if("object"!==n)return n;const r=e.constructor;return null==r||r===Object?n:r.name},p=e=>"boolean"==typeof e,y=e=>"string"==typeof e,v=e=>!isNaN(e)&&"number"==typeof e,m=Array.isArray,b=e=>{if(!e)return!1;const t=Object.getPrototypeOf(e);return(t===Object.prototype||null===t)&&"object"===d(e)},g=e=>!s(e),w=e=>e instanceof Date,_=e=>e instanceof RegExp,x=e=>"function"==typeof e,k=e=>null==e,O=(e,t=!0)=>!!e||t&&""===e,E=e=>k(e)||y(e)&&!e||m(e)&&0===e.length||b(e)&&0===Object.keys(e).length,P=e=>m(e)?e:[e],S=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),C=e=>"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView(e),j=(e,t)=>{if(k(e)||p(e)||v(e)||y(e))return e;if(w(e))return new Date(e);if(_(e))return new RegExp(e);if(C(e)){return new(0,e.constructor)(e)}if(t instanceof Set||(t=new Set),t.has(e))throw i;t.add(e);try{if(m(e)){const n=new Array(e.length);for(let r=0;re===o;function I(e,t){if(A(e)||k(e))return t;if(A(t)||k(t))return e;if(s(e)||s(t))return t;m(e)&&m(t)&&h(e.length===t.length,"arrays must be of equal length to merge.");for(const n of Object.keys(t))e[n]=I(e[n],t[n]);return e}function M(e,t=u){const n=[f.init(t),f.init(t)];if(0===e.length)return[];if(e.some((e=>0===e.length)))return[];if(1===e.length)return[...e];e[e.length-1].forEach((e=>n[0].set(e,!0)));for(let r=e.length-2;r>-1;r--){if(e[r].forEach((e=>{n[0].has(e)&&n[1].set(e,!0)})),0===n[1].size)return[];n.reverse(),n[1].clear()}return Array.from(n[0].keys())}function T(e,t=1){const n=new Array;return function e(t,r){for(let o=0,i=t.length;o0||r<0)?e(t[o],Math.max(-1,r-1)):n.push(t[o])}(e,t),n}const K=Object.prototype.toString;function D(e){if(C(e))return!0;if("function"==typeof e.toString){let t=Object.getPrototypeOf(e);for(;null!==t;){if(S(t,"toString")&&t.toString!==K)return!0;t=Object.getPrototypeOf(t)}}return!1}function R(e,t){if(e===t||Object.is(e,t))return!0;if(null===e||null===t)return!1;if(typeof e!=typeof t)return!1;if("object"!=typeof e)return!1;if(e.constructor!==t.constructor)return!1;if(e instanceof Date)return+e==+t;if(e instanceof RegExp)return e.toString()===t.toString();const n=e.constructor;if(n===Array||n===Object){const n=Object.keys(e).sort(),r=Object.keys(t).sort();if(n.length!==r.length)return!1;for(let o=0,i=n[o];o{if(null===e)return"null";if(void 0===e)return"undefined";if(y(e)||v(e)||p(e))return JSON.stringify(e);if(w(e))return e.toISOString();if(_(e)||(e=>"symbol"==typeof e)(e)||x(e))return e.toString();if(C(e))return d(e)+"["+e.toString()+"]";if(t instanceof Set||(t=new Set),t.has(e))throw i;try{if(t.add(e),m(e))return"["+e.map((e=>q(e,t))).join(",")+"]";if(b(e)){return"{"+Object.keys(e).sort().map((n=>`${n}:${q(e[n],t)}`)).join()+"}"}if(D(e))return d(e)+"("+JSON.stringify(e.toString())+")";throw new Error("mingo: cannot stringify custom type without explicit toString() method.")}finally{t.delete(e)}};function N(e,t){return k(e)?null:(t=t||u)(e)}function B(e,t,n=u){if(e.length<1)return new Map;const r=new Map,o=new Map;for(let i=0;iR(e,s))):null;k(e)?(o.set(s,[u]),r.has(a)?r.get(a).push(s):r.set(a,[s])):o.get(e).push(u)}}return o}function F(e,t){return m(e)||b(e)?e[t]:void 0}function $(e,t,n){let r=0;const o=a(e)?e:function e(t,n){let o=t;for(let i=0;i0)break;r+=1;const t=n.slice(i);o=o.reduce(((n,r)=>{const o=e(r,t);return void 0!==o&&n.push(o),n}),[]);break}if(o=F(o,t),void 0===o)break}return o}(e,t.split("."));return m(o)&&n?.unwrapArray?function(e,t){if(t<1)return e;for(;t--&&1===e.length;)e=e[0];return e}(o,r):o}function L(e,t,n){const r=t.indexOf("."),i=-1==r?t:t.substring(0,r),u=t.substring(r+1),s=-1!=r;if(m(e)){const r=/^\d+$/.test(i),a=r&&n?.preserveIndex?[...e]:[];if(r){const t=parseInt(i);let r=F(e,t);s&&(r=L(r,u,n)),n?.preserveIndex?a[t]=r:a.push(r)}else for(const i of e){const e=L(i,t,n);n?.preserveMissing?a.push(null==e?o:e):(null!=e||n?.preserveIndex)&&a.push(e)}return a}const a=n?.preserveKeys?{...e}:{};let c=F(e,i);if(s&&(c=L(c,u,n)),void 0!==c)return a[i]=c,a}function U(e){if(m(e))for(let t=e.length-1;t>=0;t--)e[t]===o?e.splice(t,1):U(e[t]);else if(b(e))for(const t in e)S(e,t)&&U(e[t])}const z=/^\d+$/;function V(e,t,n,r){const o=t.split("."),i=o[0],u=o.slice(1).join(".");if(1===o.length)(b(e)||m(e)&&z.test(i))&&n(e,i);else{r?.buildGraph&&k(e[i])&&(e[i]={});const t=e[i];if(!t)return;const s=!!(o.length>1&&z.test(o[1]));m(t)&&r?.descendArray&&!s?t.forEach((e=>V(e,u,n,r))):V(t,u,n,r)}}function W(e,t,n){V(e,t,((e,t)=>{e[t]=x(n)?n(e[t]):n}),{buildGraph:!0})}function G(e,t,n){V(e,t,((e,t)=>{if(m(e)){if(/^\d+$/.test(t))e.splice(parseInt(t),1);else if(n&&n.descendArray)for(const n of e)b(n)&&delete n[t]}else b(e)&&delete e[t]}),n)}const Y=/^\$[a-zA-Z0-9_]+$/;function X(e){return Y.test(e)}function Q(e){if(a(e))return _(e)?{$regex:e}:{$eq:e};if(g(e)){if(!Object.keys(e).some(X))return{$eq:e};if(S(e,"$regex")){const t={...e};return t.$regex=new RegExp(e.$regex,e.$options),delete t.$options,t}}return e}},1035:(e,t,n)=>{"use strict";n.d(t,{x:()=>o});var r=n(744);const o=(e,t,n)=>{if((0,r.Im)(t)||!(0,r.Gv)(t))return e;let o=r.UD;const u=n.collation;return(0,r.Gv)(u)&&(0,r.Kg)(u.locale)&&(o=function(e){const t={sensitivity:i[e.strength||3],caseFirst:"off"===e.caseFirst?"false":e.caseFirst||"false",numeric:e.numericOrdering||!1,ignorePunctuation:"shifted"===e.alternate};!0===(e.caseLevel||!1)&&("base"===t.sensitivity&&(t.sensitivity="case"),"accent"===t.sensitivity&&(t.sensitivity="variant"));const n=new Intl.Collator(e.locale,t);return(e,t)=>{if(!(0,r.Kg)(e)||!(0,r.Kg)(t))return(0,r.UD)(e,t);const o=n.compare(e,t);return o<0?-1:o>0?1:0}}(u)),e.transform((e=>{const i=Object.keys(t);for(const u of i.reverse()){const i=(0,r.$z)(e,(e=>(0,r.hd)(e,u)),n.hashFunction),s=Array.from(i.keys()).sort(o);-1===t[u]&&s.reverse();let a=0;for(const t of s)for(const n of i.get(t))e[a++]=n;(0,r.vA)(a==e.length,"bug: counter must match collection size.")}return e}))},i={1:"base",2:"accent",3:"variant"}},1073:(e,t,n)=>{"use strict";n.d(t,{Pp:()=>o,WP:()=>i});n(2779);n(744);var r=n(6827);const o=(0,r.jm)(r.Pp),i=(0,r.jm)(r.WP)},1446:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(8896),o=n(1693);function i(e){return(0,o.T)(e[r.s])}},1449:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(1576);function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,(0,r.A)(e,t)}},1576:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}n.d(t,{A:()=>r})},2198:(e,t,n)=>{"use strict";n.d(t,{t:()=>o});var r=n(4629),o=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return(0,r.C6)(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){var e=this,t=e.hasError,n=e.thrownError,r=e._value;if(t)throw n;return this._throwIfClosed(),r},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(n(9092).B)},2403:(e,t,n)=>{"use strict";n.d(t,{XV:()=>o,MR:()=>i,fy:()=>u,oZ:()=>s,NV:()=>a,Q_:()=>c,C5:()=>l,GU:()=>f});var r=n(6827);const o=(0,r.jm)(r.XV),i=(0,r.jm)(r.MR),u=(0,r.jm)(r.fy),s=(0,r.jm)(r.oZ),a=(0,r.jm)(r.NV),c=(0,r.jm)(r.Q_),l=(0,r.jm)(r.C5),f=(0,r.jm)(r.GU)},2442:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7708),o=n(5307),i=n(5096),u=n(8071),s=n(4370);var a=n(1693);function c(e,t,n){return void 0===n&&(n=1/0),(0,a.T)(t)?c((function(n,i){return(0,r.T)((function(e,r){return t(n,e,i,r)}))((0,o.Tg)(e(n,i)))}),n):("number"==typeof t&&(n=t),(0,i.N)((function(t,r){return function(e,t,n,r,i,a,c,l){var f=[],h=0,d=0,p=!1,y=function(){!p||f.length||h||t.complete()},v=function(e){return h{"use strict";n.d(t,{B3:()=>u,DZ:()=>l,F5:()=>f,hu:()=>s,px:()=>h,qk:()=>i,to:()=>o});var r=n(744),o=(e=>(e[e.CLONE_OFF=0]="CLONE_OFF",e[e.CLONE_INPUT=1]="CLONE_INPUT",e[e.CLONE_OUTPUT=2]="CLONE_OUTPUT",e[e.CLONE_ALL=3]="CLONE_ALL",e))(o||{});class i{#u;#s;#a;constructor(e,t,n){this.#u=e,this.update(t,n)}static init(e,t,n){return e instanceof i?new i(e.#u,e.root??t,{...e.#a,...n,variables:Object.assign({},e.#a?.variables,n?.variables)}):new i(e,t,n)}update(e,t){this.#s=e;const n=Object.assign({},this.#a?.variables,t?.variables);return Object.keys(n).length?this.#a={...t,variables:n}:this.#a=t??{},this}getOptions(){return Object.freeze({...this.#u,context:a.from(this.#u.context)})}get root(){return this.#s}get local(){return this.#a}get idKey(){return this.#u.idKey}get collation(){return this.#u?.collation}get processingMode(){return this.#u?.processingMode||0}get useStrictMode(){return this.#u?.useStrictMode}get scriptEnabled(){return this.#u?.scriptEnabled}get useGlobalContext(){return this.#u?.useGlobalContext}get hashFunction(){return this.#u?.hashFunction}get collectionResolver(){return this.#u?.collectionResolver}get jsonSchemaValidator(){return this.#u?.jsonSchemaValidator}get variables(){return this.#u?.variables}get context(){return this.#u?.context}}function u(e){return e instanceof i?e.getOptions():Object.freeze({idKey:"_id",scriptEnabled:!0,useStrictMode:!0,useGlobalContext:!0,processingMode:0,...e,context:e?.context?a.from(e?.context):a.init()})}var s=(e=>(e.ACCUMULATOR="accumulator",e.EXPRESSION="expression",e.PIPELINE="pipeline",e.PROJECTION="projection",e.QUERY="query",e.WINDOW="window",e))(s||{});class a{#c=new Map;constructor(){}static init(){return new a}static from(e){const t=a.init();return(0,r.gD)(e)||e.#c.forEach(((e,n)=>t.addOperators(n,e))),t}addOperators(e,t){this.#c.has(e)||this.#c.set(e,{});for(const[n,r]of Object.entries(t))this.getOperator(e,n)||(this.#c.get(e)[n]=r);return this}getOperator(e,t){return(this.#c.get(e)??{})[t]??null}addAccumulatorOps(e){return this.addOperators("accumulator",e)}addExpressionOps(e){return this.addOperators("expression",e)}addQueryOps(e){return this.addOperators("query",e)}addPipelineOps(e){return this.addOperators("pipeline",e)}addProjectionOps(e){return this.addOperators("projection",e)}addWindowOps(e){return this.addOperators("window",e)}}const c=a.init();function l(e,t){for(const[n,o]of Object.entries(t)){(0,r.vA)((0,r.Tn)(o)&&(0,r.Zo)(n),`'${n}' is not a valid operator`);const t=f(e,n,null);(0,r.vA)(!t||o===t,`${n} already exists for '${e}' operators. Cannot change operator function once registered.`)}switch(e){case"accumulator":c.addAccumulatorOps(t);break;case"expression":c.addExpressionOps(t);break;case"pipeline":c.addPipelineOps(t);break;case"projection":c.addProjectionOps(t);break;case"query":c.addQueryOps(t);break;case"window":c.addWindowOps(t)}}function f(e,t,n){const{context:r,useGlobalContext:o}=n||{},i=r?r.getOperator(e,t):null;return!i&&o?c.getOperator(e,t):i}function h(e,t,n,o){const u=i.init(o,e);return n&&(0,r.Zo)(n)?y(e,t,n,u):p(e,t,u)}const d=["$$ROOT","$$CURRENT","$$REMOVE","$$NOW"];function p(e,t,n){if((0,r.Kg)(t)&&t.length>0&&"$"===t[0]){if(v.includes(t))return t;let o=n.root;const i=t.split(".");if(d.includes(i[0])){switch(i[0]){case"$$ROOT":break;case"$$CURRENT":o=e;break;case"$$REMOVE":o=void 0;break;case"$$NOW":o=new Date}t=t.slice(i[0].length+1)}else if("$$"===i[0].slice(0,2)){o=Object.assign({},n.variables,{this:e},n?.local?.variables);const u=i[0].slice(2);(0,r.vA)((0,r.zy)(o,u),`Use of undefined variable: ${u}`),t=t.slice(2)}else t=t.slice(1);return""===t?o:(0,r.hd)(o,t)}if((0,r.cy)(t))return t.map((t=>p(e,t,n)));if((0,r.Gv)(t)){const o={},i=Object.entries(t);for(const[t,u]of i){if((0,r.Zo)(t))return(0,r.vA)(1==i.length,"expression must have single operator."),y(e,u,t,n);o[t]=p(e,u,n)}return o}return t}function y(e,t,n,o){const i=f("expression",n,o);if(i)return i(e,t,o);const u=f("accumulator",n,o);return(0,r.vA)(!!u,`accumulator '${n}' is not registered.`),(0,r.cy)(e)||(e=p(e,t,o),t=null),(0,r.vA)((0,r.cy)(e),`arguments must resolve to array for ${n}.`),u(e,t,o.update(null,o.local))}const v=["$$KEEP","$$PRUNE","$$DESCEND"]},3026:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,U:()=>u});var r=n(4629),o=n(1693);function i(e){return(0,r.AQ)(this,arguments,(function(){var t,n,o;return(0,r.YH)(this,(function(i){switch(i.label){case 0:t=e.getReader(),i.label=1;case 1:i.trys.push([1,,9,10]),i.label=2;case 2:return[4,(0,r.N3)(t.read())];case 3:return n=i.sent(),o=n.value,n.done?[4,(0,r.N3)(void 0)]:[3,5];case 4:return[2,i.sent()];case 5:return[4,(0,r.N3)(o)];case 6:return[4,i.sent()];case 7:return i.sent(),[3,2];case 8:return[3,10];case 9:return t.releaseLock(),[7];case 10:return[2]}}))}))}function u(e){return(0,o.T)(null==e?void 0:e.getReader)}},3356:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(5499);var o=n(235),i=n(9852);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{X:()=>l});var r=n(4629),o=n(5096),i=Array.isArray;var u=n(5499),s=n(235),a=n(9852);function c(){for(var e=[],t=0;t{"use strict";n.d(t,{C:()=>i});var r=n(2779),o=n(744);const i=(e,t,n)=>(0,o.Im)(t)?e:(s(t,n),e.map(u(t,r.qk.init(n))));function u(e,t,n=!0){const i=t.idKey,a=Object.keys(e),c=new Array,l=new Array,f={};for(const v of a){const i=e[v];if((0,o.Et)(i)||(0,o.Lm)(i))i?l.push(v):c.push(v);else if((0,o.cy)(i))f[v]=e=>i.map((n=>(0,r.px)(e,n,null,t.update(e))??null));else if((0,o.Gv)(i)){const e=Object.keys(i),a=1==e.length?e[0]:"",c=(0,r.F5)("projection",a,t);if(c){"$slice"===a&&!(0,o.eC)(i[a]).every(o.Et)?f[v]=e=>(0,r.px)(e,i,v,t.update(e)):f[v]=e=>c(e,i[a],v,t.update(e))}else(0,o.Zo)(a)?f[v]=e=>(0,r.px)(e,i[a],a,t):(s(i,t),f[v]=e=>{if(!(0,o.zy)(e,v))return(0,r.px)(e,i,null,t);n&&t.update(e);const s=(0,o.hd)(e,v),a=u(i,t,!1);return(0,o.cy)(s)?s.map(a):(0,o.Gv)(s)?a(s):a(e)})}else f[v]=(0,o.Kg)(i)&&"$"===i[0]?e=>(0,r.px)(e,i,v,t):e=>i}const h=Object.keys(f),d=c.includes(i);if(n&&d&&1===c.length&&!l.length&&!h.length)return e=>{const t={...e};return delete t[i],t};const p=n&&!d&&!l.includes(i),y={preserveMissing:!0};return e=>{const t={};if(c.length&&!l.length){(0,o.h1)(t,e);for(const e of c)(0,o.yT)(t,e,{descendArray:!0})}for(const n of l){const r=(0,o.Rm)(e,n,y)??{};(0,o.h1)(t,r)}l.length&&(0,o.B2)(t);for(const n of h){const r=f[n](e);void 0===r?(0,o.yT)(t,n,{descendArray:!0}):(0,o.KY)(t,n,r)}return p&&(0,o.zy)(e,i)&&(t[i]=(0,o.hd)(e,i)),t}}function s(e,t){let n=!1,r=!1;for(const[i,u]of Object.entries(e))(0,o.vA)(!i.startsWith("$"),"Field names may not start with '$'."),(0,o.vA)(!i.endsWith(".$"),"Positional projection operator '$' is not supported."),i!==t?.idKey&&(0===u||!1===u?n=!0:1!==u&&!0!==u||(r=!0),(0,o.vA)(!(n&&r),"Projection cannot have a mix of inclusion and exclusion."))}},3819:(e,t,n)=>{"use strict";n.d(t,{T:()=>o});var r=n(1693);function o(e){return Symbol.asyncIterator&&(0,r.T)(null==e?void 0:e[Symbol.asyncIterator])}},3836:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}function o(e){var t=function(e,t){if("object"!=r(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t||"default");if("object"!=r(o))return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==r(t)?t:t+""}function i(e,t){for(var n=0;nu})},4134:(e,t,n)=>{"use strict";n.d(t,{c:()=>f});var r=n(8857),o=n(2258),i=n(8896),u=n(3887);function s(e){return 0===e.length?u.D:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var a=n(2236),c=n(1693),l=n(3004),f=function(){function e(e){e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var i,u=this,s=(i=e)&&i instanceof r.vU||function(e){return e&&(0,c.T)(e.next)&&(0,c.T)(e.error)&&(0,c.T)(e.complete)}(i)&&(0,o.Uv)(i)?e:new r.Ms(e,t,n);return(0,l.Y)((function(){var e=u,t=e.operator,n=e.source;s.add(t?t.call(s,n):n?u._subscribe(s):u._trySubscribe(s))})),s},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=h(t))((function(t,o){var i=new r.Ms({next:function(t){try{e(t)}catch(n){o(n),i.unsubscribe()}},error:o,complete:t});n.subscribe(i)}))},e.prototype._subscribe=function(e){var t;return null===(t=this.source)||void 0===t?void 0:t.subscribe(e)},e.prototype[i.s]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{h:()=>a});var r=n(5499),o=n(5307),i=new(n(4134).c)((function(e){return e.complete()}));var u=n(235),s=n(9852);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{l:()=>r});var r="function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"},4429:(e,t,n)=>{"use strict";function r(e){return new TypeError("You provided "+(null!==e&&"object"==typeof e?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}n.d(t,{L:()=>r})},4644:(e,t,n)=>{"use strict";n.d(t,{X:()=>f});var r=n(2779),o=n(374);var i=n(3742);var u=n(1035),s=n(744);const a={$sort:u.x,$skip:(e,t,n)=>e.drop(t),$limit:(e,t,n)=>e.take(t)};class c{#l;#f;#h;#u;#c={};#d=null;#p=[];constructor(e,t,n,r){this.#l=e,this.#f=t,this.#h=n,this.#u=r}fetch(){if(this.#d)return this.#d;this.#d=(0,o.dF)(this.#l).filter(this.#f);const e=this.#u.processingMode;e&r.to.CLONE_INPUT&&this.#d.map(s.mg);for(const t of["$sort","$skip","$limit"])(0,s.zy)(this.#c,t)&&(this.#d=a[t](this.#d,this.#c[t],this.#u));return Object.keys(this.#h).length&&(this.#d=(0,i.C)(this.#d,this.#h,this.#u)),e&r.to.CLONE_OUTPUT&&this.#d.map(s.mg),this.#d}fetchAll(){const e=(0,o.dF)([...this.#p]);return this.#p=[],(0,o.xW)(e,this.fetch())}all(){return this.fetchAll().value()}count(){return this.all().length}skip(e){return this.#c.$skip=e,this}limit(e){return this.#c.$limit=e,this}sort(e){return this.#c.$sort=e,this}collation(e){return this.#u={...this.#u,collation:e},this}next(){if(this.#p.length>0)return this.#p.pop();const e=this.fetch().next();return e.done?void 0:e.value}hasNext(){if(this.#p.length>0)return!0;const e=this.fetch().next();return!e.done&&(this.#p.push(e.value),!0)}map(e){return this.all().map(e)}forEach(e){this.all().forEach(e)}[Symbol.iterator](){return this.fetchAll()}}const l=new Set(Array.from(["$and","$or","$nor","$expr","$jsonSchema"]));class f{#y;#u;#v;constructor(e,t){this.#v=(0,s.mg)(e),this.#u=(0,r.B3)(t),this.#y=[],this.compile()}compile(){(0,s.vA)((0,s.Gv)(this.#v),`query criteria must be an object: ${JSON.stringify(this.#v)}`);const e={};for(const[t,n]of Object.entries(this.#v)){if("$where"===t)(0,s.vA)(this.#u.scriptEnabled,"$where operator requires 'scriptEnabled' option to be true."),Object.assign(e,{field:t,expr:n});else if(l.has(t))this.processOperator(t,t,n);else{(0,s.vA)(!(0,s.Zo)(t),`unknown top level operator: ${t}`);for(const[e,r]of Object.entries((0,s.S8)(n)))this.processOperator(t,e,r)}e.field&&this.processOperator(e.field,e.field,e.expr)}}processOperator(e,t,n){const o=(0,r.F5)("query",t,this.#u);(0,s.vA)(!!o,`unknown query operator ${t}`),this.#y.push(o(e,n,this.#u))}test(e){return this.#y.every((t=>t(e)))}find(e,t){return new c(e,(e=>this.test(e)),t||{},this.#u)}remove(e){return e.reduce(((e,t)=>(this.test(t)||e.push(t),e)),[])}}},4799:(e,t,n)=>{"use strict";n.d(t,{x:()=>i});var r=n(4207),o=n(1693);function i(e){return(0,o.T)(null==e?void 0:e[r.l])}},5307:(e,t,n)=>{"use strict";n.d(t,{Tg:()=>y});var r=n(4629),o=n(9739),i=n(5796),u=n(4134),s=n(1446),a=n(3819),c=n(4429),l=n(4799),f=n(3026),h=n(1693),d=n(6712),p=n(8896);function y(e){if(e instanceof u.c)return e;if(null!=e){if((0,s.l)(e))return b=e,new u.c((function(e){var t=b[p.s]();if((0,h.T)(t.subscribe))return t.subscribe(e);throw new TypeError("Provided object does not correctly implement Symbol.observable")}));if((0,o.X)(e))return m=e,new u.c((function(e){for(var t=0;t{"use strict";n.d(t,{U:()=>i});var r=n(2442),o=n(3887);function i(e){return void 0===e&&(e=1/0),(0,r.Z)(o.D,e)}},5525:(e,t,n)=>{"use strict";n.d(t,{p4:()=>r});class r{ttl;map=new Map;_to=!1;constructor(e){this.ttl=e}has(e){return this.map.has(e)}add(e){this.map.set(e,o()),this._to||(this._to=!0,setTimeout((()=>{this._to=!1,function(e){const t=o()-e.ttl,n=e.map[Symbol.iterator]();for(;;){const r=n.next().value;if(!r)return;const o=r[0];if(!(r[1]{"use strict";n.d(t,{y:()=>o});var r=n(1693);function o(e){return(0,r.T)(null==e?void 0:e.then)}},5918:(e,t,n)=>{"use strict";n.d(t,{C2:()=>d.C,xF:()=>i.x});var r=n(2779),o=n(744);n(374);Object.freeze({R5:[10,16,25,40,63],R10:[100,125,160,200,250,315,400,500,630,800],R20:[100,112,125,140,160,180,200,224,250,280,315,355,400,450,500,560,630,710,800,900],R40:[100,106,112,118,125,132,140,150,160,170,180,190,200,212,224,236,250,265,280,300,315,355,375,400,425,450,475,500,530,560,600,630,670,710,750,800,850,900,950],R80:[103,109,115,122,128,136,145,155,165,175,185,195,206,218,230,243,258,272,290,307,325,345,365,387,412,437,462,487,515,545,575,615,650,690,730,775,825,875,925,975],"1-2-5":[10,20,50],E6:[10,15,22,33,47,68],E12:[10,12,15,18,22,27,33,39,47,56,68,82],E24:[10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91],E48:[100,105,110,115,121,127,133,140,147,154,162,169,178,187,196,205,215,226,237,249,261,274,287,301,316,332,348,365,383,402,422,442,464,487,511,536,562,590,619,649,681,715,750,787,825,866,909,953],E96:[100,102,105,107,110,113,115,118,121,124,127,130,133,137,140,143,147,150,154,158,162,165,169,174,178,182,187,191,196,200,205,210,215,221,226,232,237,243,249,255,261,267,274,280,287,294,301,309,316,324,332,340,348,357,365,374,383,392,402,412,422,432,442,453,464,475,487,499,511,523,536,549,562,576,590,604,619,634,649,665,681,698,715,732,750,768,787,806,825,845,866,887,909,931,953,976],E192:[100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149,150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198,200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249,252,255,258,261,264,267,271,274,277,280,284,287,291,294,298,301,305,309,312,316,320,324,328,332,336,340,344,348,352,357,361,365,370,374,379,383,388,392,397,402,407,412,417,422,427,432,437,442,448,453,459,464,470,475,481,487,493,499,505,511,517,523,530,536,542,549,556,562,569,576,583,590,597,604,612,619,626,634,642,649,657,665,673,681,690,698,706,715,723,732,741,750,759,768,777,787,796,806,816,825,835,845,856,866,876,887,898,909,920,931,942,953,965,976,988]});new Set(["monday","mon","tuesday","tue","wednesday","wed","thursday","thu","friday","fri","saturday","sat","sunday","sun"]),Object.freeze({mon:1,tue:2,wed:3,thu:4,fri:5,sat:6,sun:7}),Object.freeze({"%Y":{name:"year",padding:4,re:/([0-9]{4})/},"%G":{name:"year",padding:4,re:/([0-9]{4})/},"%m":{name:"month",padding:2,re:/(0[1-9]|1[012])/},"%d":{name:"day",padding:2,re:/(0[1-9]|[12][0-9]|3[01])/},"%H":{name:"hour",padding:2,re:/([01][0-9]|2[0-3])/},"%M":{name:"minute",padding:2,re:/([0-5][0-9])/},"%S":{name:"second",padding:2,re:/([0-5][0-9]|60)/},"%L":{name:"millisecond",padding:3,re:/([0-9]{3})/},"%u":{name:"weekday",padding:1,re:/([1-7])/},"%U":{name:"week",padding:2,re:/([1-4][0-9]?|5[0-3]?)/},"%V":{name:"isoWeek",padding:2,re:/([1-4][0-9]?|5[0-3]?)/},"%z":{name:"timezone",padding:2,re:/(([+-][01][0-9]|2[0-3]):?([0-5][0-9])?)/},"%Z":{name:"minuteOffset",padding:3,re:/([+-][0-9]{3})/}});var i=n(1035);Object.freeze({});n(4644);var u=n(6827);(0,u.fw)(u.GU);const s=(e,t)=>(n,i,u)=>{(0,o.vA)((0,o.cy)(i),`${e}: expression must be an array.`);const s=(0,r.px)(n,i,null,u);return s.some(o.gD)?null:((0,o.vA)(s.every(o.Et),`${e}: expression must evalue to array of numbers.`),t(s))},a=(s("$bitAnd",(e=>e.reduce(((e,t)=>e&t),-1))),s("$bitOr",(e=>e.reduce(((e,t)=>e|t),0))),s("$bitXor",(e=>e.reduce(((e,t)=>e^t),0))),(0,u.fw)(u.XV),(0,u.fw)(u.MR),(0,u.fw)(u.fy),(0,u.fw)(u.NV),(0,u.fw)(u.Q_),(0,u.fw)(u.C5),(e,t)=>{const n={};return e.split("").forEach(((e,r)=>n[e]=t*(r+1))),n});a("ABCDEFGHIKLM",1),a("NOPQRSTUVWXY",-1);const c={undefined:null,null:null,NaN:NaN,Infinity:new Error,"-Infinity":new Error};function l(e,t=c){const n=Object.assign({},c,t),i=new Set(Object.keys(n));return(t,u,s)=>{const a=(0,r.px)(t,u,null,s);if(i.has(`${a}`)){const t=n[`${a}`];if(t instanceof Error)throw new o.d8(`cannot apply $${e.name} to -inf, value must in (-inf,inf)`);return t}return e(a)}}l(Math.acos,{Infinity:1/0,0:new Error}),l(Math.acosh,{Infinity:1/0,0:new Error}),l(Math.asin),l(Math.asinh,{Infinity:1/0,"-Infinity":-1/0}),l(Math.atan),l(Math.atanh,{1:1/0,"-1":-1/0}),l(Math.cos),l(Math.cosh,{"-Infinity":1/0,Infinity:1/0});const f=Math.PI/180,h=(l((e=>e*f),{Infinity:1/0,"-Infinity":1/0}),180/Math.PI);l((e=>e*h),{Infinity:1/0,"-Infinity":-1/0}),l(Math.sin),l(Math.sinh,{"-Infinity":-1/0,Infinity:1/0}),l(Math.tan),Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER;Error;var d=n(3742)},6114:(e,t,n)=>{"use strict";n.d(t,{kC:()=>N,Cs:()=>B});const r=e=>{e.previousResults.unshift(e.changeEvent.doc),e.keyDocumentMap&&e.keyDocumentMap.set(e.changeEvent.id,e.changeEvent.doc)},o=e=>{e.previousResults.push(e.changeEvent.doc),e.keyDocumentMap&&e.keyDocumentMap.set(e.changeEvent.id,e.changeEvent.doc)},i=e=>{const t=e.previousResults.shift();e.keyDocumentMap&&t&&e.keyDocumentMap.delete(t[e.queryParams.primaryKey])},u=e=>{const t=e.previousResults.pop();e.keyDocumentMap&&t&&e.keyDocumentMap.delete(t[e.queryParams.primaryKey])},s=e=>{e.keyDocumentMap&&e.keyDocumentMap.delete(e.changeEvent.id);const t=e.queryParams.primaryKey,n=e.previousResults;for(let r=0;r{const t=e.changeEvent.id,n=e.changeEvent.doc;if(e.keyDocumentMap){if(e.keyDocumentMap.has(t))return;e.keyDocumentMap.set(t,n)}else{if(e.previousResults.find((n=>n[e.queryParams.primaryKey]===t)))return}!function(e,t,n,r){var o,i=e.length,u=i-1,s=0;if(0===i)return e.push(t),0;for(;r<=u;)n(o=e[s=r+(u-r>>1)],t)<=0?r=s+1:u=s-1;n(o,t)<=0&&s++,e.splice(s,0,t)}(e.previousResults,n,e.queryParams.sortComparator,0)},c=["doNothing","insertFirst","insertLast","removeFirstItem","removeLastItem","removeFirstInsertLast","removeLastInsertFirst","removeFirstInsertFirst","removeLastInsertLast","removeExisting","replaceExisting","alwaysWrong","insertAtSortPosition","removeExistingAndInsertAtSortPosition","runFullQueryAgain","unknownAction"],l={doNothing:e=>{},insertFirst:r,insertLast:o,removeFirstItem:i,removeLastItem:u,removeFirstInsertLast:e=>{i(e),o(e)},removeLastInsertFirst:e=>{u(e),r(e)},removeFirstInsertFirst:e=>{i(e),r(e)},removeLastInsertLast:e=>{u(e),o(e)},removeExisting:s,replaceExisting:e=>{const t=e.changeEvent.doc,n=e.queryParams.primaryKey,r=e.previousResults;for(let o=0;o{const t={_id:"wrongHuman"+(new Date).getTime()};e.previousResults.length=0,e.previousResults.push(t),e.keyDocumentMap&&(e.keyDocumentMap.clear(),e.keyDocumentMap.set(t._id,t))},insertAtSortPosition:a,removeExistingAndInsertAtSortPosition:e=>{s(e),a(e)},runFullQueryAgain:e=>{throw new Error("Action runFullQueryAgain must be implemented by yourself")},unknownAction:e=>{throw new Error("Action unknownAction should never be called")}};!function(e=6){let t="";const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let r=0;r!!e.queryParams.limit,m=e=>1===e.queryParams.limit,b=e=>!!(e.queryParams.skip&&e.queryParams.skip>0),g=e=>"DELETE"===e.changeEvent.operation,w=e=>"INSERT"===e.changeEvent.operation,_=e=>"UPDATE"===e.changeEvent.operation,x=e=>v(e)&&e.previousResults.length>=e.queryParams.limit,k=e=>{const t=e.queryParams.sortFields,n=e.changeEvent.previous,r=e.changeEvent.doc;if(!r)return!1;if(!n)return!0;for(let o=0;o{const t=e.changeEvent.id;if(e.keyDocumentMap){return e.keyDocumentMap.has(t)}{const n=e.queryParams.primaryKey,r=e.previousResults;for(let e=0;e{const t=e.previousResults[0];return!(!t||t[e.queryParams.primaryKey]!==e.changeEvent.id)},P=e=>{const t=d(e.previousResults);return!(!t||t[e.queryParams.primaryKey]!==e.changeEvent.id)},S=e=>{const t=e.changeEvent.previous;if(!t)return!1;const n=e.previousResults[0];if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)<0},C=e=>{const t=e.changeEvent.previous;if(!t)return!1;const n=d(e.previousResults);if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)>0},j=e=>{const t=e.changeEvent.doc;if(!t)return!1;const n=e.previousResults[0];if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)<0},A=e=>{const t=e.changeEvent.doc;if(!t)return!1;const n=d(e.previousResults);if(!n)return!1;if(n[e.queryParams.primaryKey]===e.changeEvent.id)return!0;return e.queryParams.sortComparator(t,n)>0},I=e=>{const t=e.changeEvent.previous;return!!t&&e.queryParams.queryMatcher(t)},M=e=>{const t=e.changeEvent.doc;if(!t)return!1;return e.queryParams.queryMatcher(t)},T=e=>0===e.previousResults.length,K={0:w,1:_,2:g,3:v,4:m,5:b,6:T,7:x,8:E,9:P,10:k,11:O,12:S,13:C,14:j,15:A,16:I,17:M};let D;function R(){return D||(D=function(e){const t=new Map,n=2+2*parseInt(e.charAt(0)+e.charAt(1),10),r=f(e.substring(2,n),2);for(let a=0;afunction(e,t,n){let r=e,o=e.l;for(;;){if(r=r[t[o](n)?"1":"0"],"number"==typeof r||"string"==typeof r)return r;o=r.l}}(R(),K,e);function N(e){const t=q(e);return c[t]}function B(e,t,n,r,o){return(0,l[e])({queryParams:t,changeEvent:n,previousResults:r,keyDocumentMap:o}),r}},6343:(e,t,n)=>{"use strict";function r(e){return r=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},r(e)}n.d(t,{A:()=>u});var o=n(1576);function i(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(i=function(){return!!e})()}function u(e){var t="function"==typeof Map?new Map:void 0;return u=function(e){if(null===e||!function(e){try{return-1!==Function.toString.call(e).indexOf("[native code]")}catch(t){return"function"==typeof e}}(e))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return function(e,t,n){if(i())return Reflect.construct.apply(null,arguments);var r=[null];r.push.apply(r,t);var u=new(e.bind.apply(e,r));return n&&(0,o.A)(u,n.prototype),u}(e,arguments,r(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),(0,o.A)(n,e)},u(e)}},6823:(e,t,n)=>{"use strict";n.d(t,{P:()=>o,T:()=>i});var r=n(6827);const o=(0,r.jm)(r.P),i=(0,r.jm)(r.TU)},6827:(e,t,n)=>{"use strict";n.d(t,{C5:()=>c,GU:()=>f,Gd:()=>g,Ig:()=>w,Jy:()=>x,MR:()=>p,NV:()=>h,P:()=>b,Pp:()=>v,Q_:()=>d,TU:()=>P,WP:()=>m,XV:()=>a,fw:()=>s,fy:()=>y,jm:()=>u,oZ:()=>l});var r=n(2779),o=n(4644),i=n(744);function u(e){return(t,n,r)=>{const o={unwrapArray:!0},u=Math.max(1,t.split(".").length-1);return s=>{const a=(0,i.hd)(s,t,o);return e(a,n,{...r,depth:u})}}}function s(e){return(t,n,o)=>{const i=(0,r.px)(t,n,null,o);return e(...i)}}function a(e,t,n){return!!(0,i.n4)(e,t)||(!(!(0,i.gD)(e)||!(0,i.gD)(t))||!!(0,i.cy)(e)&&(e.some((e=>(0,i.n4)(e,t)))||(0,i.Bq)(e,n?.depth).some((e=>(0,i.n4)(e,t)))))}function c(e,t,n){return!a(e,t,n)}function l(e,t,n){return(0,i.gD)(e)?t.some((e=>null===e)):(0,i.E$)([(0,i.eC)(e),t],n?.hashFunction).length>0}function f(e,t,n){return!l(e,t,n)}function h(e,t,n){return S(e,t,((e,t)=>(0,i.UD)(e,t)<0))}function d(e,t,n){return S(e,t,((e,t)=>(0,i.UD)(e,t)<=0))}function p(e,t,n){return S(e,t,((e,t)=>(0,i.UD)(e,t)>0))}function y(e,t,n){return S(e,t,((e,t)=>(0,i.UD)(e,t)>=0))}function v(e,t,n){return(0,i.eC)(e).some((e=>2===t.length&&e%t[0]===t[1]))}function m(e,t,n){const r=(0,i.eC)(e),o=e=>(0,i.Kg)(e)&&(0,i.vN)(t.exec(e),n?.useStrictMode);return r.some(o)||(0,i.Bq)(r,1).some(o)}function b(e,t,n){return(!1===t||0===t)&&void 0===e||(!0===t||1===t)&&void 0!==e}function g(e,t,n){if(!((0,i.cy)(e)&&(0,i.cy)(t)&&e.length&&t.length))return!1;let r=!0;for(const o of t){if(!r)break;r=(0,i.Gv)(o)&&Object.keys(o).includes("$elemMatch")?x(e,o.$elemMatch,n):(0,i.gd)(o)?e.some((e=>"string"==typeof e&&o.test(e))):e.some((e=>(0,i.n4)(o,e)))}return r}function w(e,t,n){return Array.isArray(e)&&e.length===t}function _(e){return(0,i.Zo)(e)&&-1===["$and","$or","$nor"].indexOf(e)}function x(e,t,n){if((0,i.cy)(e)&&!(0,i.Im)(e)){let r=e=>e,i=t;Object.keys(t).every(_)&&(i={temp:t},r=e=>({temp:e}));const u=new o.X(i,n);for(let t=0,n=e.length;tnull===e,O={array:i.cy,boolean:i.Lm,bool:i.Lm,date:i.$P,number:i.Et,int:i.Et,long:i.Et,double:i.Et,decimal:i.Et,null:k,object:i.Gv,regexp:i.gd,regex:i.gd,string:i.Kg,undefined:i.gD,function:e=>{throw new i.d8("unsupported type key `function`.")},1:i.Et,2:i.Kg,3:i.Gv,4:i.cy,6:i.gD,8:i.Lm,9:i.$P,10:k,11:i.gd,16:i.Et,18:i.Et,19:i.Et};function E(e,t,n){const r=O[t];return!!r&&r(e)}function P(e,t,n){return(0,i.cy)(t)?t.findIndex((t=>E(e,t)))>=0:E(e,t)}function S(e,t,n){return(0,i.eC)(e).some((e=>(0,i.QP)(e)===(0,i.QP)(t)&&n(e,t)))}},6950:(e,t,n)=>{"use strict";n.d(t,{Jy:()=>o,Ig:()=>i});var r=n(6827);(0,r.jm)(r.Gd);const o=(0,r.jm)(r.Jy),i=(0,r.jm)(r.Ig)},7329:(e,t,n)=>{"use strict";n.d(t,{cf:()=>i});var r=n(8900);const o=Symbol.for("Dexie"),i=globalThis[o]||(globalThis[o]=r);if(r.semVer!==i.semVer)throw new Error(`Two different versions of Dexie loaded in the same app: ${r.semVer} and ${i.semVer}`);const{liveQuery:u,mergeRanges:s,rangesOverlap:a,RangeSet:c,cmp:l,Entity:f,PropModSymbol:h,PropModification:d,replacePrefix:p,add:y,remove:v}=i},7635:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});var r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this._parallels=e||1,this._qC=0,this._iC=new Set,this._lHN=0,this._hPM=new Map,this._pHM=new Map};function o(e,t){if(t){if(t._timeoutObj&&clearTimeout(t._timeoutObj),e._pHM.has(t)){var n=e._pHM.get(t);e._hPM.delete(n),e._pHM.delete(t)}e._iC.delete(t)}}function i(e){e._tryIR||0===e._iC.size||(e._tryIR=!0,setTimeout((function(){e.isIdle()?setTimeout((function(){e.isIdle()?(!function(e){0!==e._iC.size&&(e._iC.values().next().value._manRes(),setTimeout((function(){return i(e)}),0))}(e),e._tryIR=!1):e._tryIR=!1}),0):e._tryIR=!1}),0))}r.prototype={isIdle:function(){return this._qC{"use strict";n.d(t,{a6:()=>i,q3:()=>s,En:()=>a,sU:()=>u});var r=n(4644),o=n(744);const i=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression: $and expects value to be an Array.");const i=t.map((e=>new r.X(e,n)));return e=>i.every((t=>t.test(e)))},u=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression. $or expects value to be an Array");const i=t.map((e=>new r.X(e,n)));return e=>i.some((t=>t.test(e)))},s=(e,t,n)=>{(0,o.vA)((0,o.cy)(t),"Invalid expression. $nor expects value to be an array.");const r=u("$or",t,n);return e=>!r(e)},a=(e,t,n)=>{const i={};i[e]=(0,o.S8)(t);const u=new r.X(i,n);return e=>!u.test(e)}},8071:(e,t,n)=>{"use strict";function r(e,t,n,r,o){void 0===r&&(r=0),void 0===o&&(o=!1);var i=t.schedule((function(){n(),o?e.add(this.schedule(null,r)):this.unsubscribe()}),r);if(e.add(i),!o)return i}n.d(t,{N:()=>r})},8146:(e,t,n)=>{"use strict";n.d(t,{p:()=>i});var r=n(5096),o=n(4370);function i(e,t){return(0,r.N)((function(n,r){var i=0;n.subscribe((0,o._)(r,(function(n){return e.call(t,n,i++)&&r.next(n)})))}))}},8609:(e,t,n)=>{"use strict";n.d(t,{t:()=>f});var r=n(4629),o=n(9092),i={now:function(){return(i.delegate||Date).now()},delegate:void 0},u=function(e){function t(t,n,r){void 0===t&&(t=1/0),void 0===n&&(n=1/0),void 0===r&&(r=i);var o=e.call(this)||this;return o._bufferSize=t,o._windowTime=n,o._timestampProvider=r,o._buffer=[],o._infiniteTimeWindow=!0,o._infiniteTimeWindow=n===1/0,o._bufferSize=Math.max(1,t),o._windowTime=Math.max(1,n),o}return(0,r.C6)(t,e),t.prototype.next=function(t){var n=this,r=n.isStopped,o=n._buffer,i=n._infiniteTimeWindow,u=n._timestampProvider,s=n._windowTime;r||(o.push(t),!i&&o.push(u.now()+s)),this._trimBuffer(),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){this._throwIfClosed(),this._trimBuffer();for(var t=this._innerSubscribe(e),n=this._infiniteTimeWindow,r=this._buffer.slice(),o=0;o0&&(t=new a.Ms({next:function(e){return b.next(e)},error:function(e){p=!0,y(),r=l(v,i,e),b.error(e)},complete:function(){h=!0,y(),r=l(v,f),b.complete()}}),(0,s.Tg)(e).subscribe(t))}))(e)}}({connector:function(){return new u(h,t,n)},resetOnError:!0,resetOnComplete:!1,resetOnRefCountZero:d})}},8896:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r="function"==typeof Symbol&&Symbol.observable||"@@observable"},8900:function(e,t,n){e.exports=function(){"use strict";var e=function(t,n){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(t,n)},t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n.",et="String expected.",tt=[],nt="__dbnames",rt="readonly",ot="readwrite";function it(e,t){return e?t?function(){return e.apply(this,arguments)&&t.apply(this,arguments)}:e:t}var ut={type:3,lower:-1/0,lowerOpen:!1,upper:[[]],upperOpen:!1};function st(e){return"string"!=typeof e||/\./.test(e)?function(e){return e}:function(t){return void 0===t[e]&&e in t&&delete(t=j(t))[e],t}}function at(){throw W.Type()}function ct(e,t){try{var n=lt(e),r=lt(t);if(n!==r)return"Array"===n?1:"Array"===r?-1:"binary"===n?1:"binary"===r?-1:"string"===n?1:"string"===r?-1:"Date"===n?1:"Date"!==r?NaN:-1;switch(n){case"number":case"Date":case"string":return tn+u&&o(n+h)}))}))}var i=vt(n)&&n.limit===1/0&&("function"!=typeof e||e===St)&&{index:n.index,range:n.range};return o(0).then((function(){if(0=o}))).length?(t.forEach((function(e){c.push((function(){var t=l,n=e._cfg.dbschema;hn(r,t,a),hn(r,n,a),l=r._dbSchema=n;var u=sn(t,n);u.add.forEach((function(e){an(a,e[0],e[1].primKey,e[1].indexes)})),u.change.forEach((function(e){if(e.recreate)throw new W.Upgrade("Not yet support for changing primary key");var t=a.objectStore(e.name);e.add.forEach((function(e){return ln(t,e)})),e.change.forEach((function(e){t.deleteIndex(e.name),ln(t,e)})),e.del.forEach((function(e){return t.deleteIndex(e)}))}));var c=e._cfg.contentUpgrade;if(c&&e._cfg.version>o){en(r,a),s._memoizedTables={};var f=k(n);u.del.forEach((function(e){f[e]=t[e]})),nn(r,[r.Transaction.prototype]),tn(r,[r.Transaction.prototype],i(f),f),s.schema=f;var h,d=q(c);return d&&Le(),u=xe.follow((function(){var e;(h=c(s))&&d&&(e=Ue.bind(null,null),h.then(e,e))})),h&&"function"==typeof h.then?xe.resolve(h):u.then((function(){return h}))}})),c.push((function(t){var n,o,i=e._cfg.dbschema;n=i,o=t,[].slice.call(o.db.objectStoreNames).forEach((function(e){return null==n[e]&&o.db.deleteObjectStore(e)})),nn(r,[r.Transaction.prototype]),tn(r,[r.Transaction.prototype],r._storeNames,r._dbSchema),s.schema=r._dbSchema})),c.push((function(t){r.idbdb.objectStoreNames.contains("$meta")&&(Math.ceil(r.idbdb.version/10)===e._cfg.version?(r.idbdb.deleteObjectStore("$meta"),delete r._dbSchema.$meta,r._storeNames=r._storeNames.filter((function(e){return"$meta"!==e}))):t.objectStore("$meta").put(e._cfg.version,"version"))}))})),function e(){return c.length?xe.resolve(c.shift()(s.idbtrans)).then(e):xe.resolve()}().then((function(){cn(l,a)}))):xe.resolve();var r,o,s,a,c,l})).catch(s)):(i(o).forEach((function(e){an(n,e,o[e].primKey,o[e].indexes)})),en(e,n),void xe.follow((function(){return e.on.populate.fire(u)})).catch(s));var r,c}))}function un(e,t){cn(e._dbSchema,t),t.db.version%10!=0||t.objectStoreNames.contains("$meta")||t.db.createObjectStore("$meta").add(Math.ceil(t.db.version/10-1),"version");var n=fn(0,e.idbdb,t);hn(e,e._dbSchema,t);for(var r=0,o=sn(n,e._dbSchema).change;rMath.pow(2,62)?0:r.oldVersion,h=r<1,e.idbdb=d.result,u&&un(e,f),on(e,r/10,f,c))}),c),d.onsuccess=Ke((function(){f=null;var n,s,c,p,y,v=e.idbdb=d.result,b=m(v.objectStoreNames);if(0t.limit?n.length=t.limit:e.length===t.limit&&n.length=r.limit&&(!r.values||e.req.values)&&Hn(e.req.query.range,r.query.range)})),!1,o,i];case"count":return u=i.find((function(e){return Qn(e.req.query.range,r.query.range)})),[u,!!u,o,i]}}(n,r,"query",e),a=s[0],c=s[1],l=s[2],f=s[3];return a&&c?a.obsSet=e.obsSet:(c=o.query(e).then((function(e){var n=e.result;if(a&&(a.res=n),t){for(var r=0,o=n.length;r{"use strict";n.d(t,{B:()=>c});var r=n(4629),o=n(4134),i=n(2258),u=(0,n(5383).L)((function(e){return function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"}})),s=n(34),a=n(3004),c=function(e){function t(){var t=e.call(this)||this;return t.closed=!1,t.currentObservers=null,t.observers=[],t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return(0,r.C6)(t,e),t.prototype.lift=function(e){var t=new l(this,this);return t.operator=e,t},t.prototype._throwIfClosed=function(){if(this.closed)throw new u},t.prototype.next=function(e){var t=this;(0,a.Y)((function(){var n,o;if(t._throwIfClosed(),!t.isStopped){t.currentObservers||(t.currentObservers=Array.from(t.observers));try{for(var i=(0,r.Ju)(t.currentObservers),u=i.next();!u.done;u=i.next()){u.value.next(e)}}catch(s){n={error:s}}finally{try{u&&!u.done&&(o=i.return)&&o.call(i)}finally{if(n)throw n.error}}}}))},t.prototype.error=function(e){var t=this;(0,a.Y)((function(){if(t._throwIfClosed(),!t.isStopped){t.hasError=t.isStopped=!0,t.thrownError=e;for(var n=t.observers;n.length;)n.shift().error(e)}}))},t.prototype.complete=function(){var e=this;(0,a.Y)((function(){if(e._throwIfClosed(),!e.isStopped){e.isStopped=!0;for(var t=e.observers;t.length;)t.shift().complete()}}))},t.prototype.unsubscribe=function(){this.isStopped=this.closed=!0,this.observers=this.currentObservers=null},Object.defineProperty(t.prototype,"observed",{get:function(){var e;return(null===(e=this.observers)||void 0===e?void 0:e.length)>0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(t){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,t)},t.prototype._subscribe=function(e){return this._throwIfClosed(),this._checkFinalizedStatuses(e),this._innerSubscribe(e)},t.prototype._innerSubscribe=function(e){var t=this,n=this,r=n.hasError,o=n.isStopped,u=n.observers;return r||o?i.Kn:(this.currentObservers=null,u.push(e),new i.yU((function(){t.currentObservers=null,(0,s.o)(u,e)})))},t.prototype._checkFinalizedStatuses=function(e){var t=this,n=t.hasError,r=t.thrownError,o=t.isStopped;n?e.error(r):o&&e.complete()},t.prototype.asObservable=function(){var e=new o.c;return e.source=this,e},t.create=function(e,t){return new l(e,t)},t}(o.c),l=function(e){function t(t,n){var r=e.call(this)||this;return r.destination=t,r.source=n,r}return(0,r.C6)(t,e),t.prototype.next=function(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.next)||void 0===n||n.call(t,e)},t.prototype.error=function(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.error)||void 0===n||n.call(t,e)},t.prototype.complete=function(){var e,t;null===(t=null===(e=this.destination)||void 0===e?void 0:e.complete)||void 0===t||t.call(e)},t.prototype._subscribe=function(e){var t,n;return null!==(n=null===(t=this.source)||void 0===t?void 0:t.subscribe(e))&&void 0!==n?n:i.Kn},t}(c)},9739:(e,t,n)=>{"use strict";n.d(t,{X:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9852:(e,t,n)=>{"use strict";n.d(t,{H:()=>_});var r=n(5307),o=n(8071),i=n(5096),u=n(4370);function s(e,t){return void 0===t&&(t=0),(0,i.N)((function(n,r){n.subscribe((0,u._)(r,(function(n){return(0,o.N)(r,e,(function(){return r.next(n)}),t)}),(function(){return(0,o.N)(r,e,(function(){return r.complete()}),t)}),(function(n){return(0,o.N)(r,e,(function(){return r.error(n)}),t)})))}))}function a(e,t){return void 0===t&&(t=0),(0,i.N)((function(n,r){r.add(e.schedule((function(){return n.subscribe(r)}),t))}))}var c=n(4134);var l=n(4207),f=n(1693);function h(e,t){if(!e)throw new Error("Iterable cannot be null");return new c.c((function(n){(0,o.N)(n,t,(function(){var r=e[Symbol.asyncIterator]();(0,o.N)(n,t,(function(){r.next().then((function(e){e.done?n.complete():n.next(e.value)}))}),0,!0)}))}))}var d=n(1446),p=n(5796),y=n(9739),v=n(4799),m=n(3819),b=n(4429),g=n(3026);function w(e,t){if(null!=e){if((0,d.l)(e))return function(e,t){return(0,r.Tg)(e).pipe(a(t),s(t))}(e,t);if((0,y.X)(e))return function(e,t){return new c.c((function(n){var r=0;return t.schedule((function(){r===e.length?n.complete():(n.next(e[r++]),n.closed||this.schedule())}))}))}(e,t);if((0,p.y)(e))return function(e,t){return(0,r.Tg)(e).pipe(a(t),s(t))}(e,t);if((0,m.T)(e))return h(e,t);if((0,v.x)(e))return function(e,t){return new c.c((function(n){var r;return(0,o.N)(n,t,(function(){r=e[l.l](),(0,o.N)(n,t,(function(){var e,t,o;try{t=(e=r.next()).value,o=e.done}catch(i){return void n.error(i)}o?n.complete():n.next(t)}),0,!0)})),function(){return(0,f.T)(null==r?void 0:r.return)&&r.return()}}))}(e,t);if((0,g.U)(e))return function(e,t){return h((0,g.C)(e),t)}(e,t)}throw(0,b.L)(e)}function _(e,t){return t?w(e,t):(0,r.Tg)(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/8070e160.82a19cdb.js b/docs/assets/js/8070e160.82a19cdb.js deleted file mode 100644 index 9f1707e027a..00000000000 --- a/docs/assets/js/8070e160.82a19cdb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[3822],{7580:(e,t,n)=>{n.d(t,{g:()=>r});var a=n(4848);function r(e){const t=[];let n=null;return e.children.forEach((e=>{e.props.id?(n&&t.push(n),n={headline:e,paragraphs:[]}):n&&n.paragraphs.push(e)})),n&&t.push(n),(0,a.jsx)("div",{style:s.stepsContainer,children:t.map(((e,t)=>(0,a.jsxs)("div",{style:s.stepWrapper,children:[(0,a.jsxs)("div",{style:s.stepIndicator,children:[(0,a.jsxs)("div",{style:s.stepNumber,children:[t+1,"."]}),(0,a.jsx)("div",{style:s.verticalLine})]}),(0,a.jsxs)("div",{style:s.stepContent,children:[(0,a.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,t)=>(0,a.jsx)("div",{style:s.item,children:e},t)))]})]},t)))})}const s={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var a=n(6540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}},9575:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"quickstart","title":"\ud83d\ude80 Quickstart","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing.","source":"@site/docs/quickstart.md","sourceDirName":".","slug":"/quickstart.html","permalink":"/quickstart.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"\ud83d\ude80 Quickstart","slug":"quickstart.html","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing."},"sidebar":"tutorialSidebar","next":{"title":"Installation","permalink":"/install.html"}}');var r=n(4848),s=n(8453),i=n(7580);const o={title:"\ud83d\ude80 Quickstart",slug:"quickstart.html",description:"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing."},l="RxDB Quickstart",d={},c=[{value:"Installation",id:"installation",level:3},{value:"Import",id:"import",level:3},{value:"Dev-Mode",id:"dev-mode",level:3},{value:"Create a Database",id:"create-a-database",level:3},{value:"Add a Collection",id:"add-a-collection",level:3},{value:"Insert a document",id:"insert-a-document",level:3},{value:"Run a Query",id:"run-a-query",level:3},{value:"Update a Document",id:"update-a-document",level:3},{value:"Delete a document",id:"delete-a-document",level:3},{value:"Observe a Query",id:"observe-a-query",level:3},{value:"Observe a Document value",id:"observe-a-document-value",level:3},{value:"Start the Replication",id:"start-the-replication",level:3},{value:"Next steps",id:"next-steps",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"rxdb-quickstart",children:"RxDB Quickstart"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the RxDB Quickstart. Here we'll learn how to create a simple real-time app with the RxDB database that is able to store and query data persistently in a browser and does realtime updates to the UI on changes."}),"\n",(0,r.jsx)("center",{children:(0,r.jsx)("a",{href:"https://rxdb.info/",children:(0,r.jsx)("img",{src:"/files/logo/rxdb_javascript_database.svg",alt:"JavaScript Embedded Database",width:"220"})})}),"\n",(0,r.jsxs)(i.g,{children:[(0,r.jsx)(t.h3,{id:"installation",children:"Installation"}),(0,r.jsx)(t.p,{children:"Install the RxDB library and the RxJS dependency:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"npm install rxdb rxjs\n"})}),(0,r.jsx)(t.h3,{id:"import",children:"Import"}),(0,r.jsx)(t.p,{children:"Import RxDB and the dev-mode plugin, the Dexie-based storage (IndexedDB) and a schema validator:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { addRxPlugin, createRxDatabase } from 'rxdb/plugins/core';\nimport { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\nimport { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';\n"})}),(0,r.jsx)(t.h3,{id:"dev-mode",children:"Dev-Mode"}),(0,r.jsxs)(t.p,{children:["When you use RxDB in development, you should always enable the ",(0,r.jsx)(t.a,{href:"/dev-mode.html",children:"dev-mode plugin"}),", which adds helpful checks and validations, and tells you if you do something wrong."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"addRxPlugin(RxDBDevModePlugin);\n"})}),(0,r.jsx)(t.h3,{id:"create-a-database",children:"Create a Database"}),(0,r.jsxs)(t.p,{children:["For the database, here we use the ",(0,r.jsx)(t.a,{href:"/rx-storage-dexie.html",children:"RxDB Dexie Storage"})," that stores data inside of IndexedDB in a browser. For other JavaScript runtimes, you would not use the dexie storage but one of the other ",(0,r.jsx)(t.a,{href:"/rx-storage.html",children:"RxDB Storages"}),"."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const myDatabase = await createRxDatabase({\n name: 'mydatabase',\n storage: wrappedValidateAjvStorage({\n storage: getRxStorageDexie()\n })\n});\n"})}),(0,r.jsx)(t.h3,{id:"add-a-collection",children:"Add a Collection"}),(0,r.jsxs)(t.p,{children:["An RxDatabase contains ",(0,r.jsx)(t.a,{href:"/rx-collection.html",children:"RxCollection"}),"s for storing and querying data. A collection is similar to an SQL table, and individual records are stored in the collection as JSON documents. An ",(0,r.jsx)(t.a,{href:"/rx-database.html",children:"RxDatabase"})," can have as many collections as you need.\nAdd a collection with a ",(0,r.jsx)(t.a,{href:"/rx-schema.html",children:"schema"})," to the database:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"await myDatabase.addCollections({\n // name of the collection\n todos: {\n // we use the JSON-schema standard\n schema: {\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100 // <- the primary key must have maxLength\n },\n name: {\n type: 'string'\n },\n done: {\n type: 'boolean'\n },\n timestamp: {\n type: 'string',\n format: 'date-time'\n }\n },\n required: ['id', 'name', 'done', 'timestamp']\n }\n }\n});\n"})}),(0,r.jsx)(t.h3,{id:"insert-a-document",children:"Insert a document"}),(0,r.jsxs)(t.p,{children:["Now that we have an RxCollection we can store some ",(0,r.jsx)(t.a,{href:"/rx-document.html",children:"documents"})," in it."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const myDocument = await myDatabase.todos.insert({\n id: 'todo1',\n name: 'Learn RxDB',\n done: false,\n timestamp: new Date().toISOString()\n});\n"})}),(0,r.jsx)(t.h3,{id:"run-a-query",children:"Run a Query"}),(0,r.jsxs)(t.p,{children:["Execute a ",(0,r.jsx)(t.a,{href:"/rx-query.html",children:"query"})," that returns all found documents once:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const foundDocuments = await myDatabase.todos.find({\n selector: {\n done: {\n $eq: false\n }\n }\n}).exec();\n"})}),(0,r.jsx)(t.h3,{id:"update-a-document",children:"Update a Document"}),(0,r.jsxs)(t.p,{children:["In the first found document, set ",(0,r.jsx)(t.code,{children:"done"})," to ",(0,r.jsx)(t.code,{children:"true"}),":"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const firstDocument = foundDocuments[0];\nawait firstDocument.patch({\n done: true\n});\n"})}),(0,r.jsx)(t.h3,{id:"delete-a-document",children:"Delete a document"}),(0,r.jsx)(t.p,{children:"Delete the document so that it can no longer be found in queries:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"await firstDocument.remove();\n"})}),(0,r.jsx)(t.h3,{id:"observe-a-query",children:"Observe a Query"}),(0,r.jsxs)(t.p,{children:["Subscribe to data changes so that your UI is always up-to-date with the data stored on disk. RxDB allows you to subscribe to data changes even when the change happens in another part of your application, another browser tab, or during database ",(0,r.jsx)(t.a,{href:"/replication.html",children:"replication/synchronization"}),":"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const observable = myDatabase.todos.find({\n selector: {\n done: {\n $eq: false\n }\n }\n}).$ // get the observable via RxQuery.$;\nobservable.subscribe(notDoneDocs => {\n console.log('Currently have ' + notDoneDocs.length + ' things to do');\n // -> here you would re-render your app to show the updated document list\n});\n"})}),(0,r.jsx)(t.h3,{id:"observe-a-document-value",children:"Observe a Document value"}),(0,r.jsxs)(t.p,{children:["You can also subscribe to the fields of a single RxDocument. Add the ",(0,r.jsx)(t.code,{children:"$"})," sign to the desired field and then subscribe to the returned observable."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"myDocument.done$.subscribe(isDone => {\n console.log('done: ' + isDone);\n});\n"})}),(0,r.jsx)(t.h3,{id:"start-the-replication",children:"Start the Replication"}),(0,r.jsxs)(t.p,{children:["RxDB has multiple ",(0,r.jsx)(t.a,{href:"/replication.html",children:"replication plugins"})," to replicate database state with a server.\nThe easiest way to replicate data between your clients' devices is the ",(0,r.jsx)(t.a,{href:"/replication-webrtc.html",children:"WebRTC replication plugin"})," that replicates data between devices without a centralized server. This makes it easy to try out replication without having to host anything:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import {\n replicateWebRTC,\n getConnectionHandlerSimplePeer\n} from 'rxdb/plugins/replication-webrtc';\nreplicateWebRTC({\n collection: myDatabase.todos,\n connectionHandlerCreator: getConnectionHandlerSimplePeer({}),\n topic: '', // <- set any app-specific room id here.\n secret: 'mysecret',\n pull: {},\n push: {}\n})\n"})})]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsx)(t.p,{children:"You are now ready to dive deeper into RxDB."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Start reading the full documentation ",(0,r.jsx)(t.a,{href:"/install.html",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["There is a full implementation of the ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb-quickstart",children:"quickstart guide"})," so you can clone that repository and play with the code."]}),"\n",(0,r.jsxs)(t.li,{children:["For frameworks and runtimes like Angular, React Native and others, check out the list of ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb/tree/master/examples",children:"example implementations"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Also please continue reading the documentation, join the community on our ",(0,r.jsx)(t.a,{href:"/chat/",children:"Discord chat"}),", and star the ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb",children:"GitHub repo"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["If you are using RxDB in a production environment and are able to support its continued development, please take a look at the ",(0,r.jsx)(t.a,{href:"/premium/",children:"\ud83d\udc51 Premium package"})," which includes additional plugins and utilities."]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/8070e160.a42f7cf5.js b/docs/assets/js/8070e160.a42f7cf5.js new file mode 100644 index 00000000000..183d28884ec --- /dev/null +++ b/docs/assets/js/8070e160.a42f7cf5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[3822],{7580:(e,t,n)=>{n.d(t,{g:()=>r});var a=n(4848);function r(e){const t=[];let n=null;return e.children.forEach((e=>{e.props.id?(n&&t.push(n),n={headline:e,paragraphs:[]}):n&&n.paragraphs.push(e)})),n&&t.push(n),(0,a.jsx)("div",{style:i.stepsContainer,children:t.map(((e,t)=>(0,a.jsxs)("div",{style:i.stepWrapper,children:[(0,a.jsxs)("div",{style:i.stepIndicator,children:[(0,a.jsxs)("div",{style:i.stepNumber,children:[t+1,"."]}),(0,a.jsx)("div",{style:i.verticalLine})]}),(0,a.jsxs)("div",{style:i.stepContent,children:[(0,a.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,t)=>(0,a.jsx)("div",{style:i.item,children:e},t)))]})]},t)))})}const i={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var a=n(6540);const r={},i=a.createContext(r);function s(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(i.Provider,{value:t},e.children)}},9575:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"quickstart","title":"\ud83d\ude80 Quickstart","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing.","source":"@site/docs/quickstart.md","sourceDirName":".","slug":"/quickstart.html","permalink":"/quickstart.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"\ud83d\ude80 Quickstart","slug":"quickstart.html","description":"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing."},"sidebar":"tutorialSidebar","previous":{"title":"Overview","permalink":"/overview.html"},"next":{"title":"Installation","permalink":"/install.html"}}');var r=n(4848),i=n(8453),s=n(7580);const o={title:"\ud83d\ude80 Quickstart",slug:"quickstart.html",description:"Learn how to build a realtime app with RxDB. Follow this quickstart for setup, schema creation, data operations, and real-time syncing."},l="RxDB Quickstart",d={},c=[{value:"Installation",id:"installation",level:3},{value:"Import",id:"import",level:3},{value:"Dev-Mode",id:"dev-mode",level:3},{value:"Create a Database",id:"create-a-database",level:3},{value:"Add a Collection",id:"add-a-collection",level:3},{value:"Insert a document",id:"insert-a-document",level:3},{value:"Run a Query",id:"run-a-query",level:3},{value:"Update a Document",id:"update-a-document",level:3},{value:"Delete a document",id:"delete-a-document",level:3},{value:"Observe a Query",id:"observe-a-query",level:3},{value:"Observe a Document value",id:"observe-a-document-value",level:3},{value:"Start the Replication",id:"start-the-replication",level:3},{value:"Next steps",id:"next-steps",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"rxdb-quickstart",children:"RxDB Quickstart"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the RxDB Quickstart. Here we'll learn how to create a simple real-time app with the RxDB database that is able to store and query data persistently in a browser and does realtime updates to the UI on changes."}),"\n",(0,r.jsx)("center",{children:(0,r.jsx)("a",{href:"https://rxdb.info/",children:(0,r.jsx)("img",{src:"/files/logo/rxdb_javascript_database.svg",alt:"JavaScript Embedded Database",width:"220"})})}),"\n",(0,r.jsxs)(s.g,{children:[(0,r.jsx)(t.h3,{id:"installation",children:"Installation"}),(0,r.jsx)(t.p,{children:"Install the RxDB library and the RxJS dependency:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"npm install rxdb rxjs\n"})}),(0,r.jsx)(t.h3,{id:"import",children:"Import"}),(0,r.jsx)(t.p,{children:"Import RxDB and the dev-mode plugin, the Dexie-based storage (IndexedDB) and a schema validator:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { addRxPlugin, createRxDatabase } from 'rxdb/plugins/core';\nimport { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\nimport { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';\n"})}),(0,r.jsx)(t.h3,{id:"dev-mode",children:"Dev-Mode"}),(0,r.jsxs)(t.p,{children:["When you use RxDB in development, you should always enable the ",(0,r.jsx)(t.a,{href:"/dev-mode.html",children:"dev-mode plugin"}),", which adds helpful checks and validations, and tells you if you do something wrong."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"addRxPlugin(RxDBDevModePlugin);\n"})}),(0,r.jsx)(t.h3,{id:"create-a-database",children:"Create a Database"}),(0,r.jsxs)(t.p,{children:["For the database, here we use the ",(0,r.jsx)(t.a,{href:"/rx-storage-dexie.html",children:"RxDB Dexie Storage"})," that stores data inside of IndexedDB in a browser. For other JavaScript runtimes, you would not use the dexie storage but one of the other ",(0,r.jsx)(t.a,{href:"/rx-storage.html",children:"RxDB Storages"}),"."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const myDatabase = await createRxDatabase({\n name: 'mydatabase',\n storage: wrappedValidateAjvStorage({\n storage: getRxStorageDexie()\n })\n});\n"})}),(0,r.jsx)(t.h3,{id:"add-a-collection",children:"Add a Collection"}),(0,r.jsxs)(t.p,{children:["An RxDatabase contains ",(0,r.jsx)(t.a,{href:"/rx-collection.html",children:"RxCollection"}),"s for storing and querying data. A collection is similar to an SQL table, and individual records are stored in the collection as JSON documents. An ",(0,r.jsx)(t.a,{href:"/rx-database.html",children:"RxDatabase"})," can have as many collections as you need.\nAdd a collection with a ",(0,r.jsx)(t.a,{href:"/rx-schema.html",children:"schema"})," to the database:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"await myDatabase.addCollections({\n // name of the collection\n todos: {\n // we use the JSON-schema standard\n schema: {\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100 // <- the primary key must have maxLength\n },\n name: {\n type: 'string'\n },\n done: {\n type: 'boolean'\n },\n timestamp: {\n type: 'string',\n format: 'date-time'\n }\n },\n required: ['id', 'name', 'done', 'timestamp']\n }\n }\n});\n"})}),(0,r.jsx)(t.h3,{id:"insert-a-document",children:"Insert a document"}),(0,r.jsxs)(t.p,{children:["Now that we have an RxCollection we can store some ",(0,r.jsx)(t.a,{href:"/rx-document.html",children:"documents"})," in it."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const myDocument = await myDatabase.todos.insert({\n id: 'todo1',\n name: 'Learn RxDB',\n done: false,\n timestamp: new Date().toISOString()\n});\n"})}),(0,r.jsx)(t.h3,{id:"run-a-query",children:"Run a Query"}),(0,r.jsxs)(t.p,{children:["Execute a ",(0,r.jsx)(t.a,{href:"/rx-query.html",children:"query"})," that returns all found documents once:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const foundDocuments = await myDatabase.todos.find({\n selector: {\n done: {\n $eq: false\n }\n }\n}).exec();\n"})}),(0,r.jsx)(t.h3,{id:"update-a-document",children:"Update a Document"}),(0,r.jsxs)(t.p,{children:["In the first found document, set ",(0,r.jsx)(t.code,{children:"done"})," to ",(0,r.jsx)(t.code,{children:"true"}),":"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const firstDocument = foundDocuments[0];\nawait firstDocument.patch({\n done: true\n});\n"})}),(0,r.jsx)(t.h3,{id:"delete-a-document",children:"Delete a document"}),(0,r.jsx)(t.p,{children:"Delete the document so that it can no longer be found in queries:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"await firstDocument.remove();\n"})}),(0,r.jsx)(t.h3,{id:"observe-a-query",children:"Observe a Query"}),(0,r.jsxs)(t.p,{children:["Subscribe to data changes so that your UI is always up-to-date with the data stored on disk. RxDB allows you to subscribe to data changes even when the change happens in another part of your application, another browser tab, or during database ",(0,r.jsx)(t.a,{href:"/replication.html",children:"replication/synchronization"}),":"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"const observable = myDatabase.todos.find({\n selector: {\n done: {\n $eq: false\n }\n }\n}).$ // get the observable via RxQuery.$;\nobservable.subscribe(notDoneDocs => {\n console.log('Currently have ' + notDoneDocs.length + ' things to do');\n // -> here you would re-render your app to show the updated document list\n});\n"})}),(0,r.jsx)(t.h3,{id:"observe-a-document-value",children:"Observe a Document value"}),(0,r.jsxs)(t.p,{children:["You can also subscribe to the fields of a single RxDocument. Add the ",(0,r.jsx)(t.code,{children:"$"})," sign to the desired field and then subscribe to the returned observable."]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"myDocument.done$.subscribe(isDone => {\n console.log('done: ' + isDone);\n});\n"})}),(0,r.jsx)(t.h3,{id:"start-the-replication",children:"Start the Replication"}),(0,r.jsxs)(t.p,{children:["RxDB has multiple ",(0,r.jsx)(t.a,{href:"/replication.html",children:"replication plugins"})," to replicate database state with a server.\nThe easiest way to replicate data between your clients' devices is the ",(0,r.jsx)(t.a,{href:"/replication-webrtc.html",children:"WebRTC replication plugin"})," that replicates data between devices without a centralized server. This makes it easy to try out replication without having to host anything:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import {\n replicateWebRTC,\n getConnectionHandlerSimplePeer\n} from 'rxdb/plugins/replication-webrtc';\nreplicateWebRTC({\n collection: myDatabase.todos,\n connectionHandlerCreator: getConnectionHandlerSimplePeer({}),\n topic: '', // <- set any app-specific room id here.\n secret: 'mysecret',\n pull: {},\n push: {}\n})\n"})})]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsx)(t.p,{children:"You are now ready to dive deeper into RxDB."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Start reading the full documentation ",(0,r.jsx)(t.a,{href:"/install.html",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["There is a full implementation of the ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb-quickstart",children:"quickstart guide"})," so you can clone that repository and play with the code."]}),"\n",(0,r.jsxs)(t.li,{children:["For frameworks and runtimes like Angular, React Native and others, check out the list of ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb/tree/master/examples",children:"example implementations"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Also please continue reading the documentation, join the community on our ",(0,r.jsx)(t.a,{href:"/chat/",children:"Discord chat"}),", and star the ",(0,r.jsx)(t.a,{href:"https://github.com/pubkey/rxdb",children:"GitHub repo"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["If you are using RxDB in a production environment and are able to support its continued development, please take a look at the ",(0,r.jsx)(t.a,{href:"/premium/",children:"\ud83d\udc51 Premium package"})," which includes additional plugins and utilities."]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/8164.d67687c2.js b/docs/assets/js/8164.d67687c2.js new file mode 100644 index 00000000000..48bd4ad9dfc --- /dev/null +++ b/docs/assets/js/8164.d67687c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[8164],{1990:(e,t,r)=>{r.d(t,{Ks:()=>n,V0:()=>a});var a=async function(e){var t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.prototype.map.call(new Uint8Array(r),(e=>("00"+e.toString(16)).slice(-2))).join("")};function n(e){for(var t=0,r=e.length,a=0;a{r.d(t,{L$:()=>s,Z2:()=>i,zs:()=>n});var a="abcdefghijklmnopqrstuvwxyz";function n(e){void 0===e&&(e=10);for(var t="",r=0;r{r.r(t),r.d(t,{getDatabase:()=>ta,hasIndexedDB:()=>ea});var a=r(7329);function n(e,t){var r=e.get(t);if(void 0===r)throw new Error("missing value from map "+t);return r}function i(e,t,r,a){var n=e.get(t);return void 0===n?(n=r(),e.set(t,n)):a&&a(n),n}function s(e){return Object.assign({},e)}function o(e,t){if(void 0===t&&(t=!1),!e)return e;if(!t&&Array.isArray(e))return e.sort(((e,t)=>"string"==typeof e&&"string"==typeof t?e.localeCompare(t):"object"==typeof e?1:-1)).map((e=>o(e,t)));if("object"==typeof e&&!Array.isArray(e)){var r={};return Object.keys(e).sort(((e,t)=>e.localeCompare(t))).forEach((a=>{r[a]=o(e[a],t)})),r}return e}var c=function e(t){if(!t)return t;if(null===t||"object"!=typeof t)return t;if(Array.isArray(t)){for(var r=new Array(t.length),a=r.length;a--;)r[a]=e(t[a]);return r}var n={};for(var i in t)n[i]=e(t[i]);return n};function u(e,t,r){return Object.defineProperty(e,t,{get:function(){return r}}),r}var h=e=>{var t=typeof e;return null!==e&&("object"===t||"function"===t)},l=new Set(["__proto__","prototype","constructor"]),d=new Set("0123456789");function m(e){var t=[],r="",a="start",n=!1;for(var i of e)switch(i){case"\\":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a)throw new Error("Invalid character after an index");n&&(r+=i),a="property",n=!n;break;case".":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a){a="property";break}if(n){n=!1,r+=i;break}if(l.has(r))return[];t.push(r),r="",a="property";break;case"[":if("index"===a)throw new Error("Invalid character in an index");if("indexEnd"===a){a="index";break}if(n){n=!1,r+=i;break}if("property"===a){if(l.has(r))return[];t.push(r),r=""}a="index";break;case"]":if("index"===a){t.push(Number.parseInt(r,10)),r="",a="indexEnd";break}if("indexEnd"===a)throw new Error("Invalid character after an index");default:if("index"===a&&!d.has(i))throw new Error("Invalid character in an index");if("indexEnd"===a)throw new Error("Invalid character after an index");"start"===a&&(a="property"),n&&(n=!1,r+="\\"),r+=i}switch(n&&(r+="\\"),a){case"property":if(l.has(r))return[];t.push(r);break;case"index":throw new Error("Index was not closed");case"start":t.push("")}return t}function f(e,t){if("number"!=typeof t&&Array.isArray(e)){var r=Number.parseInt(t,10);return Number.isInteger(r)&&e[r]===e[t]}return!1}function p(e,t){if(f(e,t))throw new Error("Cannot use string index")}function v(e,t,r){if(Array.isArray(t)&&(t=t.join(".")),!t.includes(".")&&!t.includes("["))return e[t];if(!h(e)||"string"!=typeof t)return void 0===r?e:r;var a=m(t);if(0===a.length)return r;for(var n=0;n!1,deepFreezeWhenDevMode:e=>e,tunnelErrorMessage:e=>"\n RxDB Error-Code: "+e+".\n Hint: Error messages are not included in RxDB core to reduce build size.\n To show the full error messages and to ensure that you do not make any mistakes when using RxDB,\n use the dev-mode plugin when you are in development mode: https://rxdb.info/dev-mode.html?console=error\n "};function k(e,t,r){return"\n"+e+"\n"+function(e){var t="";return 0===Object.keys(e).length?t:(t+="-".repeat(20)+"\n",t+="Parameters:\n",t+=Object.keys(e).map((t=>{var r="[object Object]";try{r="errors"===t?e[t].map((e=>JSON.stringify(e,Object.getOwnPropertyNames(e)))):JSON.stringify(e[t],(function(e,t){return void 0===t?null:t}),2)}catch(a){}return t+": "+r})).join("\n"),t+="\n")}(r)}var _=function(e){function t(t,r,a){var n;void 0===a&&(a={});var i=k(r,0,a);return(n=e.call(this,i)||this).code=t,n.message=i,n.url=E(t),n.parameters=a,n.rxdb=!0,n}return(0,w.A)(t,e),t.prototype.toString=function(){return this.message},(0,b.A)(t,[{key:"name",get:function(){return"RxError ("+this.code+")"}},{key:"typeError",get:function(){return!1}}])}((0,D.A)(Error)),I=function(e){function t(t,r,a){var n;void 0===a&&(a={});var i=k(r,0,a);return(n=e.call(this,i)||this).code=t,n.message=i,n.url=E(t),n.parameters=a,n.rxdb=!0,n}return(0,w.A)(t,e),t.prototype.toString=function(){return this.message},(0,b.A)(t,[{key:"name",get:function(){return"RxTypeError ("+this.code+")"}},{key:"typeError",get:function(){return!0}}])}((0,D.A)(TypeError));function E(e){return"https://rxdb.info/errors.html?console=errors#"+e}function R(e){return"\nFind out more about this error here: "+E(e)+" \n"}function C(e,t){return new _(e,x.tunnelErrorMessage(e)+R(e),t)}function O(e,t){return new I(e,x.tunnelErrorMessage(e)+R(e),t)}function S(e){return!(!e||409!==e.status)&&e}var P={409:"document write conflict",422:"schema validation error",510:"attachment data missing"};function j(e){return C("COL20",{name:P[e.status],document:e.documentId,writeError:e})}var $=/\./g,N=r(7587);function A(e,t){var r=t;return r="properties."+(r=r.replace($,".properties.")),v(e,r=(0,N.L$)(r))}function B(e){return"string"==typeof e?e:e.key}function M(e,t){if("string"==typeof e.primaryKey)return t[e.primaryKey];var r=e.primaryKey;return r.fields.map((e=>{var r=v(t,e);if(void 0===r)throw C("DOC18",{args:{field:e,documentData:t}});return r})).join(r.separator)}function q(e){var t=B((e=s(e)).primaryKey);e.properties=s(e.properties),e.additionalProperties=!1,Object.prototype.hasOwnProperty.call(e,"keyCompression")||(e.keyCompression=!1),e.indexes=e.indexes?e.indexes.slice(0):[],e.required=e.required?e.required.slice(0):[],e.encrypted=e.encrypted?e.encrypted.slice(0):[],e.properties._rev={type:"string",minLength:1},e.properties._attachments={type:"object"},e.properties._deleted={type:"boolean"},e.properties._meta=T,e.required=e.required?e.required.slice(0):[],e.required.push("_deleted"),e.required.push("_rev"),e.required.push("_meta"),e.required.push("_attachments");var r=L(e);(0,g.Hb)(e.required,r),e.required=e.required.filter((e=>!e.includes("."))).filter(((e,t,r)=>r.indexOf(e)===t)),e.version=e.version||0;var a=e.indexes.map((e=>{var r=(0,g.k_)(e)?e.slice(0):[e];return r.includes(t)||r.push(t),"_deleted"!==r[0]&&r.unshift("_deleted"),r}));0===a.length&&a.push(function(e){return["_deleted",e]}(t)),a.push(["_meta.lwt",t]),e.internalIndexes&&e.internalIndexes.map((e=>{a.push(e)}));var n=new Set;return a.filter((e=>{var t=e.join(",");return!n.has(t)&&(n.add(t),!0)})),e.indexes=a,e}var T={type:"object",properties:{lwt:{type:"number",minimum:1,maximum:1e15,multipleOf:.01}},additionalProperties:!0,required:["lwt"]};function L(e){var t=Object.keys(e.properties).filter((t=>e.properties[t].final)),r=B(e.primaryKey);return t.push(r),"string"!=typeof e.primaryKey&&e.primaryKey.fields.forEach((e=>t.push(e))),t}var Q="docs",F="changes",W="attachments",H="dexie",K=new Map,z=new Map;var Z="__";function U(e){var t=e.split(".");if(t.length>1)return t.map((e=>U(e))).join(".");if(e.startsWith("|")){var r=e.substring(1);return Z+r}return e}function V(e){var t=e.split(".");return t.length>1?t.map((e=>V(e))).join("."):e.startsWith(Z)?"|"+e.substring(Z.length):e}function J(e,t){if(!t)return t;var r=s(t);return r=Y(r),e.forEach((e=>{var a=v(t,e)?"1":"0",n=U(e);y(r,n,a)})),r}function G(e,t){return t?(t=X(t=s(t)),e.forEach((e=>{var r=v(t,e);y(t,e,"1"===r)})),t):t}function Y(e){if(!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e))return e.map((e=>Y(e)));if("object"==typeof e){var t={};return Object.entries(e).forEach((e=>{let[r,a]=e;"object"==typeof a&&(a=Y(a)),t[U(r)]=a})),t}}function X(e){if(!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e))return e.map((e=>X(e)));if("object"==typeof e){var t={};return Object.entries(e).forEach((r=>{let[a,n]=r;("object"==typeof n||Array.isArray(e))&&(n=X(n)),t[V(a)]=n})),t}}function ee(e){var t=[],r=B(e.primaryKey);t.push([r]),t.push(["_deleted",r]),e.indexes&&e.indexes.forEach((e=>{var r=(0,g.$r)(e);t.push(r)})),t.push(["_meta.lwt",r]),t.push(["_meta.lwt"]);var a=(t=t.map((e=>e.map((e=>U(e)))))).map((e=>1===e.length?e[0]:"["+e.join("+")+"]"));return(a=a.filter(((e,t,r)=>r.indexOf(e)===t))).join(", ")}async function te(e,t){var r=await e;return(await r.dexieTable.bulkGet(t)).map((e=>G(r.booleanIndexes,e)))}function re(e,t){return e+"||"+t}function ae(e){var t=new Set,r=[];return e.indexes?(e.indexes.forEach((a=>{(0,g.$r)(a).forEach((a=>{t.has(a)||(t.add(a),"boolean"===A(e,a).type&&r.push(a))}))})),r.push("_deleted"),(0,g.jw)(r)):r}var ne=r(9092),ie=0;function se(){var e=Date.now();(e+=.01)<=ie&&(e=ie+.01);var t=parseFloat(e.toFixed(2));return ie=t,t}var oe={},ce=r(1990),ue=r(8289),he=ue.Dr,le=!1;async function de(){return le?he:(le=!0,he=(async()=>!(!oe.premium||"string"!=typeof oe.premium||"6da4936d1425ff3a5c44c02342c6daf791d266be3ae8479b8ec59e261df41b93"!==await(0,ce.V0)(oe.premium)))())}var me=r(4978),fe=String.fromCharCode(65535),pe=Number.MIN_SAFE_INTEGER;function ve(e,t){var r=t.selector,a=e.indexes?e.indexes.slice(0):[];t.index&&(a=[t.index]);var n=!!t.sort.find((e=>"desc"===Object.values(e)[0])),i=new Set;Object.keys(r).forEach((t=>{var a=A(e,t);a&&"boolean"===a.type&&Object.prototype.hasOwnProperty.call(r[t],"$eq")&&i.add(t)}));var s,o=t.sort.map((e=>Object.keys(e)[0])).filter((e=>!i.has(e))).join(","),c=-1;if(a.forEach((e=>{var a=!0,u=!0,h=e.map((e=>{var t=r[e],n=t?Object.keys(t):[],i={};t&&n.length?n.forEach((e=>{if(ye.has(e)){var r=function(e,t){switch(e){case"$eq":return{startKey:t,endKey:t,inclusiveEnd:!0,inclusiveStart:!0};case"$lte":return{endKey:t,inclusiveEnd:!0};case"$gte":return{startKey:t,inclusiveStart:!0};case"$lt":return{endKey:t,inclusiveEnd:!1};case"$gt":return{startKey:t,inclusiveStart:!1};default:throw new Error("SNH")}}(e,t[e]);i=Object.assign(i,r)}})):i={startKey:u?pe:fe,endKey:a?fe:pe,inclusiveStart:!0,inclusiveEnd:!0};return void 0===i.startKey&&(i.startKey=pe),void 0===i.endKey&&(i.endKey=fe),void 0===i.inclusiveStart&&(i.inclusiveStart=!0),void 0===i.inclusiveEnd&&(i.inclusiveEnd=!0),u&&!i.inclusiveStart&&(u=!1),a&&!i.inclusiveEnd&&(a=!1),i})),l=h.map((e=>e.startKey)),d=h.map((e=>e.endKey)),m={index:e,startKeys:l,endKeys:d,inclusiveEnd:a,inclusiveStart:u,sortSatisfiedByIndex:!n&&o===e.filter((e=>!i.has(e))).join(","),selectorSatisfiedByIndex:we(e,t.selector,l,d)},f=function(e,t,r){var a=0,n=e=>{e>0&&(a+=e)},i=10,s=(0,g.Sd)(r.startKeys,(e=>e!==pe&&e!==fe));n(s*i);var o=(0,g.Sd)(r.startKeys,(e=>e!==fe&&e!==pe));n(o*i);var c=(0,g.Sd)(r.startKeys,((e,t)=>e===r.endKeys[t]));n(c*i*1.5);var u=r.sortSatisfiedByIndex?5:0;return n(u),a}(0,0,m);(f>=c||t.index)&&(c=f,s=m)})),!s)throw C("SNH",{query:t});return s}var ye=new Set(["$eq","$gt","$gte","$lt","$lte"]),ge=new Set(["$eq","$gt","$gte"]),be=new Set(["$eq","$lt","$lte"]);function we(e,t,r,a){var n=Object.entries(t).find((t=>{let[r,a]=t;return!e.includes(r)||Object.entries(a).find((e=>{let[t,r]=e;return!ye.has(t)}))}));if(n)return!1;if(t.$and||t.$or)return!1;var i=[],s=new Set;for(var[o,c]of Object.entries(t)){if(!e.includes(o))return!1;var u=Object.keys(c).filter((e=>ge.has(e)));if(u.length>1)return!1;var h=u[0];if(h&&s.add(o),"$eq"!==h){if(i.length>0)return!1;i.push(h)}}var l=[],d=new Set;for(var[m,f]of Object.entries(t)){if(!e.includes(m))return!1;var p=Object.keys(f).filter((e=>be.has(e)));if(p.length>1)return!1;var v=p[0];if(v&&d.add(m),"$eq"!==v){if(l.length>0)return!1;l.push(v)}}var y=0;for(var g of e){for(var b of[s,d]){if(!b.has(g)&&b.size>0)return!1;b.delete(g)}if(r[y]!==a[y]&&s.size>0&&d.size>0)return!1;y++}return!0}var De=r(744),xe=r(2779),ke=r(4644),_e=r(5918),Ie=r(7705),Ee=r(2403),Re=r(1073),Ce=r(6950),Oe=r(6823),Se=!1;function Pe(e){return Se||((0,xe.DZ)(xe.hu.PIPELINE,{$sort:_e.xF,$project:_e.C2}),(0,xe.DZ)(xe.hu.QUERY,{$and:Ie.a6,$eq:Ee.XV,$elemMatch:Ce.Jy,$exists:Oe.P,$gt:Ee.MR,$gte:Ee.fy,$in:Ee.oZ,$lt:Ee.NV,$lte:Ee.Q_,$ne:Ee.C5,$nin:Ee.GU,$mod:Re.Pp,$nor:Ie.q3,$not:Ie.En,$or:Ie.sU,$regex:Re.WP,$size:Ce.Ig,$type:Oe.T}),Se=!0),new ke.X(e)}function je(e,t){var r=B(e.primaryKey);t=s(t);var a=c(t);if("number"!=typeof a.skip&&(a.skip=0),a.selector?(a.selector=a.selector,Object.entries(a.selector).forEach((e=>{let[t,r]=e;"object"==typeof r&&null!==r||(a.selector[t]={$eq:r})}))):a.selector={},a.index){var n=(0,g.$r)(a.index);n.includes(r)||n.push(r),a.index=n}if(a.sort)a.sort.find((e=>{return t=e,Object.keys(t)[0]===r;var t}))||(a.sort=a.sort.slice(0),a.sort.push({[r]:"asc"}));else if(a.index)a.sort=a.index.map((e=>({[e]:"asc"})));else{if(e.indexes){var i=new Set;Object.entries(a.selector).forEach((e=>{let[t,r]=e;("object"!=typeof r||null===r||!!Object.keys(r).find((e=>ye.has(e))))&&i.add(t)}));var o,u=-1;e.indexes.forEach((e=>{var t=(0,g.k_)(e)?e:[e],r=t.findIndex((e=>!i.has(e)));r>0&&r>u&&(u=r,o=t)})),o&&(a.sort=o.map((e=>({[e]:"asc"}))))}a.sort||(a.sort=[{[r]:"asc"}])}return a}function $e(e,t){if(!t.sort)throw C("SNH",{query:t});var r=[];t.sort.forEach((e=>{var t,a,n,i=Object.keys(e)[0],s=Object.values(e)[0];r.push({key:i,direction:s,getValueFn:(t=i,a=t.split("."),n=a.length,1===n?e=>e[t]:e=>{for(var t=e,r=0;r{for(var a=0;ar.test(e)}async function Ae(e,t){var r=await e.exec();return r?Array.isArray(r)?Promise.all(r.map((e=>t(e)))):r instanceof Map?Promise.all([...r.values()].map((e=>t(e)))):await t(r):null}function Be(e,t){if(!t.sort)throw C("SNH",{query:t});return{query:t,queryPlan:ve(e,t)}}function Me(e){return e===pe?-1/0:e}function qe(e,t,r){return e.includes(t)?r===fe||!0===r?"1":"0":r}function Te(e,t,r){if(!r){if("undefined"==typeof window)throw new Error("IDBKeyRange missing");r=window.IDBKeyRange}var a=t.startKeys.map(((r,a)=>{var n=t.index[a];return qe(e,n,r)})).map(Me),n=t.endKeys.map(((r,a)=>{var n=t.index[a];return qe(e,n,r)})).map(Me);return r.bound(a,n,!t.inclusiveStart,!t.inclusiveEnd)}async function Le(e,t){var r=await e.internals,a=t.query,n=a.skip?a.skip:0,i=n+(a.limit?a.limit:1/0),s=t.queryPlan,o=!1;s.selectorSatisfiedByIndex||(o=Ne(e.schema,t.query));var c=Te(r.booleanIndexes,s,r.dexieDb._options.IDBKeyRange),u=s.index,h=[];if(await r.dexieDb.transaction("r",r.dexieTable,(async e=>{var t,a=e.idbtrans.objectStore(Q);t="["+u.map((e=>U(e))).join("+")+"]";var n=a.index(t).openCursor(c);await new Promise((e=>{n.onsuccess=function(t){var a=t.target.result;if(a){var n=G(r.booleanIndexes,a.value);o&&!o(n)||h.push(n),s.sortSatisfiedByIndex&&h.length===i?e():a.continue()}else e()}}))})),!s.sortSatisfiedByIndex){var l=$e(e.schema,t.query);h=h.sort(l)}return{documents:h=h.slice(n,i)}}function Qe(e){for(var t="",r=0;r0&&We[e].forEach((e=>e(t)))}async function Ke(e,t){for(var r of We[e])await r(t)}var ze="_rxdb_internal";async function Ze(e,t){var r=(await e.findDocumentsById([t],!1))[0];return r||void 0}async function Ue(e,t,r){var a=await e.bulkWrite([t],r);if(a.error.length>0)throw a.error[0];return rt(B(e.schema.primaryKey),[t],a)[0]}function Ve(e,t,r,a){if(a)throw 409===a.status?C("CONFLICT",{collection:e.name,id:t,writeError:a,data:r}):422===a.status?C("VD2",{collection:e.name,id:t,writeError:a,data:r}):a}function Je(e){return{previous:e.previous,document:Ge(e.document)}}function Ge(e){if(!e._attachments||0===Object.keys(e._attachments).length)return e;var t=s(e);return t._attachments={},Object.entries(e._attachments).forEach((e=>{let[r,a]=e;var n,i,s;t._attachments[r]=(s=(n=a).data)?{length:(i=s,atob(i).length),digest:n.digest,type:n.type}:n})),t}function Ye(e){return Object.assign({},e,{_meta:s(e._meta)})}function Xe(e,t,r){x.deepFreezeWhenDevMode(r);var a=B(t.schema.primaryKey),n={originalStorageInstance:t,schema:t.schema,internals:t.internals,collectionName:t.collectionName,databaseName:t.databaseName,options:t.options,async bulkWrite(r,n){for(var i=e.token,s=new Array(r.length),o=se(),c=0;ct.bulkWrite(s,n))),m={error:[]};et.set(m,s);var f=0===d.error.length?[]:d.error.filter((e=>!(409!==e.status||e.writeRow.previous||e.writeRow.document._deleted||!(0,me.ZN)(e.documentInDb)._deleted)||(m.error.push(e),!1)));if(f.length>0){var p=new Set,v=f.map((t=>(p.add(t.documentId),{previous:t.documentInDb,document:Object.assign({},t.writeRow.document,{_rev:Fe(e.token,t.documentInDb)})}))),y=await e.lockedRun((()=>t.bulkWrite(v,n)));(0,g.Hb)(m.error,y.error);var b=rt(a,s,m,p),w=rt(a,v,y);return(0,g.Hb)(b,w),m}return m},query:r=>e.lockedRun((()=>t.query(r))),count:r=>e.lockedRun((()=>t.count(r))),findDocumentsById:(r,a)=>e.lockedRun((()=>t.findDocumentsById(r,a))),getAttachmentData:(r,a,n)=>e.lockedRun((()=>t.getAttachmentData(r,a,n))),getChangedDocumentsSince:t.getChangedDocumentsSince?(r,a)=>e.lockedRun((()=>t.getChangedDocumentsSince((0,me.ZN)(r),a))):void 0,cleanup:r=>e.lockedRun((()=>t.cleanup(r))),remove:()=>(e.storageInstances.delete(n),e.lockedRun((()=>t.remove()))),close:()=>(e.storageInstances.delete(n),e.lockedRun((()=>t.close()))),changeStream:()=>t.changeStream()};return e.storageInstances.add(n),n}var et=new WeakMap,tt=new WeakMap;function rt(e,t,r,a){return i(tt,r,(()=>{var n=[],i=et.get(r);if(i||(i=t),r.error.length>0||a){for(var s=a||new Set,o=0;o{r.storageName===e&&r.databaseName===t.databaseName&&r.collectionName===t.collectionName&&r.version===t.schema.version&&i.next(r.eventBulk)};n.addEventListener("message",s);var o=r.changeStream(),c=!1,u=o.subscribe((r=>{c||n.postMessage({storageName:e,databaseName:t.databaseName,collectionName:t.collectionName,version:t.schema.version,eventBulk:r})}));r.changeStream=function(){return i.asObservable().pipe((0,at.X)(o))};var h=r.close.bind(r);r.close=async function(){return c=!0,u.unsubscribe(),n.removeEventListener("message",s),a||await st(t.databaseInstanceToken,r),h()};var l=r.remove.bind(r);r.remove=async function(){return c=!0,u.unsubscribe(),n.removeEventListener("message",s),a||await st(t.databaseInstanceToken,r),l()}}}var ct=se(),ut=!1,ht=function(){function e(e,t,r,a,n,i,s,o){this.changes$=new ne.B,this.instanceId=ct++,this.storage=e,this.databaseName=t,this.collectionName=r,this.schema=a,this.internals=n,this.options=i,this.settings=s,this.devMode=o,this.primaryPath=B(this.schema.primaryKey)}var t=e.prototype;return t.bulkWrite=async function(e,t){dt(this),ut||await de()||console.warn(["-------------- RxDB Open Core RxStorage -------------------------------","You are using the free Dexie.js based RxStorage implementation from RxDB https://rxdb.info/rx-storage-dexie.html?console=dexie ","While this is a great option, we want to let you know that there are faster storage solutions available in our premium plugins.","For professional users and production environments, we highly recommend considering these premium options to enhance performance and reliability."," https://rxdb.info/premium/?console=dexie ","If you already purchased premium access you can disable this log by calling the setPremiumFlag() function from rxdb-premium/plugins/shared.","---------------------------------------------------------------------"].join("\n")),ut=!0,e.forEach((e=>{if(!e.document._rev||e.previous&&!e.previous._rev)throw C("SNH",{args:{row:e}})}));var r=await this.internals,a={error:[]};this.devMode&&(e=e.map((e=>{var t=Ye(e.document);return{previous:e.previous,document:t}})));var n,i=e.map((e=>e.document[this.primaryPath]));if(await r.dexieDb.transaction("rw",r.dexieTable,r.dexieAttachmentsTable,(async()=>{var s=new Map;(await te(this.internals,i)).forEach((e=>{var t=e;return t&&s.set(t[this.primaryPath],t),t})),n=function(e,t,r,a,n,i,s){for(var o,c=!!e.schema.attachments,u=[],h=[],l=[],d={id:(0,N.zs)(10),events:[],checkpoint:null,context:n},m=d.events,f=[],p=[],v=[],y=r.size>0,g=a.length,b=function(){var e,n=a[w],d=n.document,g=n.previous,b=d[t],D=d._deleted,x=g&&g._deleted,k=void 0;if(y&&(k=r.get(b)),k){var _=k._rev;if(!g||g&&_!==g._rev){var I={isError:!0,status:409,documentId:b,writeRow:n,documentInDb:k};return l.push(I),1}var E=c?Je(n):n;c&&(D?g&&Object.keys(g._attachments).forEach((e=>{p.push({documentId:b,attachmentId:e,digest:(0,me.ZN)(g)._attachments[e].digest})})):(Object.entries(d._attachments).find((t=>{let[r,a]=t;return(g?g._attachments[r]:void 0)||a.data||(e={documentId:b,documentInDb:k,isError:!0,status:510,writeRow:n,attachmentId:r}),!0})),e||Object.entries(d._attachments).forEach((e=>{let[t,r]=e;var a=g?g._attachments[t]:void 0;if(a){var n=E.document._attachments[t].digest;r.data&&a.digest!==n&&v.push({documentId:b,attachmentId:t,attachmentData:r,digest:r.digest})}else f.push({documentId:b,attachmentId:t,attachmentData:r,digest:r.digest})})))),e?l.push(e):(c?(h.push(Je(E)),s&&s(d)):(h.push(E),s&&s(d)),o=E);var R=null,O=null,S=null;if(x&&!D)S="INSERT",R=c?Ge(d):d;else if(!g||x||D){if(!D)throw C("SNH",{args:{writeRow:n}});S="DELETE",R=(0,me.ZN)(d),O=g}else S="UPDATE",R=c?Ge(d):d,O=g;var P={documentId:b,documentData:R,previousDocumentData:O,operation:S};m.push(P)}else{var j=!!D;if(c&&Object.entries(d._attachments).forEach((t=>{let[r,a]=t;a.data?f.push({documentId:b,attachmentId:r,attachmentData:a,digest:a.digest}):(e={documentId:b,isError:!0,status:510,writeRow:n,attachmentId:r},l.push(e))})),e||(c?(u.push(Je(n)),i&&i(d)):(u.push(n),i&&i(d)),o=n),!j){var $={documentId:b,operation:"INSERT",documentData:c?Ge(d):d,previousDocumentData:c&&g?Ge(g):g};m.push($)}}},w=0;w{o.push(e.document)})),n.bulkUpdateDocs.forEach((e=>{o.push(e.document)})),(o=o.map((e=>J(r.booleanIndexes,e)))).length>0&&await r.dexieTable.bulkPut(o);var c=[];n.attachmentsAdd.forEach((e=>{c.push({id:re(e.documentId,e.attachmentId),data:e.attachmentData.data})})),n.attachmentsUpdate.forEach((e=>{c.push({id:re(e.documentId,e.attachmentId),data:e.attachmentData.data})})),await r.dexieAttachmentsTable.bulkPut(c),await r.dexieAttachmentsTable.bulkDelete(n.attachmentsRemove.map((e=>re(e.documentId,e.attachmentId))))})),(n=(0,me.ZN)(n)).eventBulk.events.length>0){var s=(0,me.ZN)(n.newestRow).document;n.eventBulk.checkpoint={id:s[this.primaryPath],lwt:s._meta.lwt},this.changes$.next(n.eventBulk)}return a},t.findDocumentsById=async function(e,t){dt(this);var r=await this.internals,a=[];return await r.dexieDb.transaction("r",r.dexieTable,(async()=>{(await te(this.internals,e)).forEach((e=>{!e||e._deleted&&!t||a.push(e)}))})),a},t.query=function(e){return dt(this),Le(this,e)},t.count=async function(e){if(e.queryPlan.selectorSatisfiedByIndex){var t=await async function(e,t){var r=await e.internals,a=t.queryPlan,n=a.index,i=Te(r.booleanIndexes,a,r.dexieDb._options.IDBKeyRange),s=-1;return await r.dexieDb.transaction("r",r.dexieTable,(async e=>{var t,r=e.idbtrans.objectStore(Q);t="["+n.map((e=>U(e))).join("+")+"]";var a=r.index(t).count(i);s=await new Promise(((e,t)=>{a.onsuccess=function(){e(a.result)},a.onerror=e=>t(e)}))})),s}(this,e);return{count:t,mode:"fast"}}return{count:(await Le(this,e)).documents.length,mode:"slow"}},t.changeStream=function(){return dt(this),this.changes$.asObservable()},t.cleanup=async function(e){dt(this);var t=await this.internals;return await t.dexieDb.transaction("rw",t.dexieTable,(async()=>{var r=se()-e,a=await t.dexieTable.where("_meta.lwt").below(r).toArray(),n=[];a.forEach((e=>{"1"===e._deleted&&n.push(e[this.primaryPath])})),await t.dexieTable.bulkDelete(n)})),!0},t.getAttachmentData=async function(e,t,r){dt(this);var a=await this.internals,n=re(e,t);return await a.dexieDb.transaction("r",a.dexieAttachmentsTable,(async()=>{var r=await a.dexieAttachmentsTable.get(n);if(r)return r.data;throw new Error("attachment missing documentId: "+e+" attachmentId: "+t)}))},t.remove=async function(){dt(this);var e=await this.internals;return await e.dexieTable.clear(),this.close()},t.close=function(){return this.closed||(this.closed=(async()=>{this.changes$.complete(),await async function(e){var t=await e,r=z.get(e)-1;0===r?(t.dexieDb.close(),z.delete(e)):z.set(e,r)}(this.internals)})()),this.closed},e}();async function lt(e,t,r){var n=function(e,t,r,n){var o="rxdb-dexie-"+e+"--"+n.version+"--"+t,c=i(K,o,(()=>{var e=(async()=>{var e=s(r);e.autoOpen=!1;var t=new a.cf(o,e),i={[Q]:ee(n),[F]:"++sequence, id",[W]:"id"};return t.version(1).stores(i),await t.open(),{dexieDb:t,dexieTable:t[Q],dexieAttachmentsTable:t[W],booleanIndexes:ae(n)}})();return K.set(o,c),z.set(c,0),e}));return c}(t.databaseName,t.collectionName,r,t.schema),o=new ht(e,t.databaseName,t.collectionName,t.schema,n,t.options,r,t.devMode);return await ot(H,t,o),Promise.resolve(o)}function dt(e){if(e.closed)throw new Error("RxStorageInstanceDexie is closed "+e.databaseName+"-"+e.collectionName)}var mt="16.6.1",ft=function(){function e(e){this.name=H,this.rxdbVersion=mt,this.settings=e}return e.prototype.createStorageInstance=function(e){(function(e){if(e.schema.keyCompression)throw C("UT5",{args:{params:e}});if((t=e.schema).encrypted&&t.encrypted.length>0||t.attachments&&t.attachments.encrypted)throw C("UT6",{args:{params:e}});var t;if(e.schema.attachments&&e.schema.attachments.compression)throw C("UT7",{args:{params:e}})}(e),e.schema.indexes)&&e.schema.indexes.flat().filter((e=>!e.includes("."))).forEach((t=>{if(!e.schema.required||!e.schema.required.includes(t))throw C("DXE1",{field:t,schema:e.schema})}));return lt(this,e,this.settings)},e}();var pt=r(7593),vt=function(){function e(e,t){if(this.jsonSchema=e,this.hashFunction=t,this.indexes=function(e){return(e.indexes||[]).map((e=>(0,g.k_)(e)?e:[e]))}(this.jsonSchema),this.primaryPath=B(this.jsonSchema.primaryKey),!e.properties[this.primaryPath].maxLength)throw C("SC39",{schema:e});this.finalFields=L(this.jsonSchema)}var t=e.prototype;return t.validateChange=function(e,t){this.finalFields.forEach((r=>{if(!(0,pt.b)(e[r],t[r]))throw C("DOC9",{dataBefore:e,dataAfter:t,fieldName:r,schema:this.jsonSchema})}))},t.getDocumentPrototype=function(){var e={},t=A(this.jsonSchema,"");return Object.keys(t).forEach((t=>{var r=t;e.__defineGetter__(t,(function(){if(this.get&&"function"==typeof this.get)return this.get(r)})),Object.defineProperty(e,t+"$",{get:function(){return this.get$(r)},enumerable:!1,configurable:!1}),Object.defineProperty(e,t+"$$",{get:function(){return this.get$$(r)},enumerable:!1,configurable:!1}),Object.defineProperty(e,t+"_",{get:function(){return this.populate(r)},enumerable:!1,configurable:!1})})),u(this,"getDocumentPrototype",(()=>e)),e},t.getPrimaryOfDocumentData=function(e){return M(this.jsonSchema,e)},(0,b.A)(e,[{key:"version",get:function(){return this.jsonSchema.version}},{key:"defaultValues",get:function(){var e={};return Object.entries(this.jsonSchema.properties).filter((e=>{let[,t]=e;return Object.prototype.hasOwnProperty.call(t,"default")})).forEach((t=>{let[r,a]=t;return e[r]=a.default})),u(this,"defaultValues",e)}},{key:"hash",get:function(){return u(this,"hash",this.hashFunction(JSON.stringify(this.jsonSchema)))}}])}();function yt(e,t,r){void 0===r&&(r=!0),r&&He("preCreateRxSchema",e);var a=q(e);a=function(e){return o(e,!0)}(a),x.deepFreezeWhenDevMode(a);var n=new vt(a,t);return He("createRxSchema",n),n}var gt=r(7708),bt=r(8146),wt=r(3356),Dt=r(5520),xt=r(8609);function kt(e){var t=e.split("-"),r="RxDB";return t.forEach((e=>{r+=(0,N.Z2)(e)})),r+="Plugin",new Error("You are using a function which must be overwritten by a plugin.\n You should either prevent the usage of this function or add the plugin via:\n import { "+r+" } from 'rxdb/plugins/"+e+"';\n addRxPlugin("+r+");\n ")}function _t(e){return e.documentData?e.documentData:e.previousDocumentData}function It(e){switch(e.operation){case"INSERT":return{operation:e.operation,id:e.documentId,doc:e.documentData,previous:null};case"UPDATE":return{operation:e.operation,id:e.documentId,doc:x.deepFreezeWhenDevMode(e.documentData),previous:e.previousDocumentData?e.previousDocumentData:"UNKNOWN"};case"DELETE":return{operation:e.operation,id:e.documentId,doc:null,previous:e.previousDocumentData}}}var Et=new Map;function Rt(e){return i(Et,e,(()=>{for(var t=new Array(e.events.length),r=e.events,a=e.collectionName,n=e.isLocal,i=x.deepFreezeWhenDevMode,s=0;s[]));return new Promise(((r,n)=>{var i={lastKnownDocumentState:e,modifier:t,resolve:r,reject:n};(0,me.ZN)(a).push(i),this.triggerRun()}))},t.triggerRun=async function(){if(!0!==this.isRunning&&0!==this.queueByDocId.size){this.isRunning=!0;var e=[],t=this.queueByDocId;this.queueByDocId=new Map,await Promise.all(Array.from(t.entries()).map((async t=>{let[r,a]=t;var n,i,s,o=(n=a.map((e=>e.lastKnownDocumentState)),i=n[0],s=Qe(i._rev),n.forEach((e=>{var t=Qe(e._rev);t>s&&(i=e,s=t)})),i),u=o;for(var h of a)try{u=await h.modifier(c(u))}catch(l){h.reject(l),h.reject=()=>{},h.resolve=()=>{}}try{await this.preWrite(u,o)}catch(l){return void a.forEach((e=>e.reject(l)))}e.push({previous:o,document:u})})));var r=e.length>0?await this.storageInstance.bulkWrite(e,"incremental-write"):{error:[]};return await Promise.all(rt(this.primaryPath,e,r).map((e=>{var r=e[this.primaryPath];this.postWrite(e),n(t,r).forEach((t=>t.resolve(e)))}))),r.error.forEach((e=>{var r=e.documentId,a=n(t,r),s=S(e);if(s){var o=i(this.queueByDocId,r,(()=>[]));a.reverse().forEach((e=>{e.lastKnownDocumentState=(0,me.ZN)(s.documentInDb),(0,me.ZN)(o).unshift(e)}))}else{var c=j(e);a.forEach((e=>e.reject(c)))}})),this.isRunning=!1,this.triggerRun()}},e}();function Ot(e){return async t=>{var r=function(e){return Object.assign({},e,{_meta:void 0,_deleted:void 0,_rev:void 0})}(t);r._deleted=t._deleted;var a=await e(r),n=Object.assign({},a,{_meta:t._meta,_attachments:t._attachments,_rev:t._rev,_deleted:void 0!==a._deleted?a._deleted:t._deleted});return void 0===n._deleted&&(n._deleted=!1),n}}var St={get primaryPath(){if(this.isInstanceOfRxDocument)return this.collection.schema.primaryPath},get primary(){var e=this;if(e.isInstanceOfRxDocument)return e._data[e.primaryPath]},get revision(){if(this.isInstanceOfRxDocument)return this._data._rev},get deleted$(){if(this.isInstanceOfRxDocument)return this.$.pipe((0,gt.T)((e=>e._data._deleted)))},get deleted$$(){var e=this;return e.collection.database.getReactivityFactory().fromObservable(e.deleted$,e.getLatest().deleted,e.collection.database)},get deleted(){if(this.isInstanceOfRxDocument)return this._data._deleted},getLatest(){var e=this.collection._docCache.getLatestDocumentData(this.primary);return this.collection._docCache.getCachedRxDocument(e)},get $(){var e=this.primary;return this.collection.eventBulks$.pipe((0,bt.p)((e=>!e.isLocal)),(0,gt.T)((t=>t.events.find((t=>t.documentId===e)))),(0,bt.p)((e=>!!e)),(0,gt.T)((e=>_t((0,me.ZN)(e)))),(0,wt.Z)(this.collection._docCache.getLatestDocumentData(e)),(0,Dt.F)(((e,t)=>e._rev===t._rev)),(0,gt.T)((e=>this.collection._docCache.getCachedRxDocument(e))),(0,xt.t)(me.bz))},get $$(){var e=this;return e.collection.database.getReactivityFactory().fromObservable(e.$,e.getLatest()._data,e.collection.database)},get$(e){if(x.isDevMode()){if(e.includes(".item."))throw C("DOC1",{path:e});if(e===this.primaryPath)throw C("DOC2");if(this.collection.schema.finalFields.includes(e))throw C("DOC3",{path:e});if(!A(this.collection.schema.jsonSchema,e))throw C("DOC4",{path:e})}return this.$.pipe((0,gt.T)((t=>v(t,e))),(0,Dt.F)())},get$$(e){var t=this.get$(e);return this.collection.database.getReactivityFactory().fromObservable(t,this.getLatest().get(e),this.collection.database)},populate(e){var t=A(this.collection.schema.jsonSchema,e),r=this.get(e);if(!r)return ue.$A;if(!t)throw C("DOC5",{path:e});if(!t.ref)throw C("DOC6",{path:e,schemaObj:t});var a=this.collection.database.collections[t.ref];if(!a)throw C("DOC7",{ref:t.ref,path:e,schemaObj:t});return"array"===t.type?a.findByIds(r).exec().then((e=>{var t=e.values();return Array.from(t)})):a.findOne(r).exec()},get(e){return $t(this,e)},toJSON(e){if(void 0===e&&(e=!1),e)return x.deepFreezeWhenDevMode(this._data);var t=s(this._data);return delete t._rev,delete t._attachments,delete t._deleted,delete t._meta,x.deepFreezeWhenDevMode(t)},toMutableJSON(e){return void 0===e&&(e=!1),c(this.toJSON(e))},update(e){throw kt("update")},incrementalUpdate(e){throw kt("update")},updateCRDT(e){throw kt("crdt")},putAttachment(){throw kt("attachments")},getAttachment(){throw kt("attachments")},allAttachments(){throw kt("attachments")},get allAttachments$(){throw kt("attachments")},async modify(e,t){var r=this._data,a=await Ot(e)(r);return this._saveData(a,r)},incrementalModify(e,t){return this.collection.incrementalWriteQueue.addWrite(this._data,Ot(e)).then((e=>this.collection._docCache.getCachedRxDocument(e)))},patch(e){var t=this._data,r=c(t);return Object.entries(e).forEach((e=>{let[t,a]=e;r[t]=a})),this._saveData(r,t)},incrementalPatch(e){return this.incrementalModify((t=>(Object.entries(e).forEach((e=>{let[r,a]=e;t[r]=a})),t)))},async _saveData(e,t){if(e=s(e),this._data._deleted)throw C("DOC11",{id:this.primary,document:this});await jt(this.collection,e,t);var r=[{previous:t,document:e}],a=await this.collection.storageInstance.bulkWrite(r,"rx-document-save-data"),n=a.error[0];return Ve(this.collection,this.primary,e,n),await this.collection._runHooks("post","save",e,this),this.collection._docCache.getCachedRxDocument(rt(this.collection.schema.primaryPath,r,a)[0])},async remove(){if(this.deleted)return Promise.reject(C("DOC13",{document:this,id:this.primary}));var e=await this.collection.bulkRemove([this]);if(e.error.length>0){var t=e.error[0];Ve(this.collection,this.primary,this._data,t)}return e.success[0]},incrementalRemove(){return this.incrementalModify((async e=>(await this.collection._runHooks("pre","remove",e,this),e._deleted=!0,e))).then((async e=>(await this.collection._runHooks("post","remove",e._data,e),e)))},close(){throw C("DOC14")}};function Pt(e){void 0===e&&(e=St);var t=function(e,t){this.collection=e,this._data=t,this._propertyCache=new Map,this.isInstanceOfRxDocument=!0};return t.prototype=e,t}function jt(e,t,r){return t._meta=Object.assign({},r._meta,t._meta),x.isDevMode()&&e.schema.validateChange(r,t),e._runHooks("pre","save",t,r)}function $t(e,t){return i(e._propertyCache,t,(()=>{var r=v(e._data,t);return"object"!=typeof r||null===r||Array.isArray(r)?x.deepFreezeWhenDevMode(r):new Proxy(s(r),{get(r,a){if("string"!=typeof a)return r[a];var n=a.charAt(a.length-1);if("$"===n){if(a.endsWith("$$")){var i=a.slice(0,-2);return e.get$$((0,N.L$)(t+"."+i))}var s=a.slice(0,-1);return e.get$((0,N.L$)(t+"."+s))}if("_"===n){var o=a.slice(0,-1);return e.populate((0,N.L$)(t+"."+o))}var c=r[a];return"number"==typeof c||"string"==typeof c||"boolean"==typeof c?c:$t(e,(0,N.L$)(t+"."+a))}})}))}var Nt=r(2198),At=r(4157),Bt=r(2442),Mt=r(6114);function qt(e,t){return t.sort&&0!==t.sort.length?t.sort.map((e=>Object.keys(e)[0])):[e]}var Tt=new WeakMap;function Lt(e,t){if(!e.collection.database.eventReduce)return{runFullQueryAgain:!0};for(var r=function(e){return i(Tt,e,(()=>{var t=e.collection,r=je(t.storageInstance.schema,c(e.mangoQuery)),a=t.schema.primaryPath,n=$e(t.schema.jsonSchema,r),i=Ne(t.schema.jsonSchema,r);return{primaryKey:e.collection.schema.primaryPath,skip:r.skip,limit:r.limit,sortFields:qt(a,r),sortComparator:(t,r)=>{var a={docA:t,docB:r,rxQuery:e};return n(a.docA,a.docB)},queryMatcher:t=>i({doc:t,rxQuery:e}.doc)}}))}(e),a=(0,me.ZN)(e._result).docsData.slice(0),n=(0,me.ZN)(e._result).docsDataMap,s=!1,o=[],u=0;u{var t={queryParams:r,changeEvent:e,previousResults:a,keyDocumentMap:n},i=(0,Mt.kC)(t);return"runFullQueryAgain"===i||("doNothing"!==i?(s=!0,(0,Mt.Cs)(i,r,e,a,n),!1):void 0)}));return l?{runFullQueryAgain:!0}:{runFullQueryAgain:!1,changed:s,newResults:a}}var Qt=function(){function e(){this._map=new Map}return e.prototype.getByQuery=function(e){var t=e.toString();return i(this._map,t,(()=>e))},e}();function Ft(e,t){t.uncached=!0;var r=t.toString();e._map.delete(r)}function Wt(e){return e.refCount$.observers.length}var Ht,Kt,zt=(Ht=100,Kt=3e4,(e,t)=>{if(!(t._map.size0||(0===i._lastEnsureEqual&&i._creationTimee._lastEnsureEqual-t._lastEnsureEqual)).slice(0,s).forEach((e=>Ft(t,e)))}}),Zt=new WeakSet;var Ut=function(){function e(e,t,r){this.cacheItemByDocId=new Map,this.tasks=new Set,this.registry="function"==typeof FinalizationRegistry?new FinalizationRegistry((e=>{var t=e.docId,r=this.cacheItemByDocId.get(t);r&&(r[0].delete(e.revisionHeight),0===r[0].size&&this.cacheItemByDocId.delete(t))})):void 0,this.primaryPath=e,this.changes$=t,this.documentCreator=r,t.subscribe((e=>{this.tasks.add((()=>{for(var t=this.cacheItemByDocId,r=0;r{this.processTasks()}))}))}var t=e.prototype;return t.processTasks=function(){0!==this.tasks.size&&(Array.from(this.tasks).forEach((e=>e())),this.tasks.clear())},t.getLatestDocumentData=function(e){return this.processTasks(),n(this.cacheItemByDocId,e)[1]},t.getLatestDocumentDataIfExists=function(e){this.processTasks();var t=this.cacheItemByDocId.get(e);if(t)return t[1]},(0,b.A)(e,[{key:"getCachedRxDocuments",get:function(){return u(this,"getCachedRxDocuments",Vt(this))}},{key:"getCachedRxDocument",get:function(){var e=Vt(this);return u(this,"getCachedRxDocument",(t=>e([t])[0]))}}])}();function Vt(e){var t=e.primaryPath,r=e.cacheItemByDocId,a=e.registry,n=x.deepFreezeWhenDevMode,i=e.documentCreator;return s=>{for(var o=new Array(s.length),c=[],u=0;u0&&a&&(e.tasks.add((()=>{for(var e=0;e{e.processTasks()}))),o}}function Jt(e,t){return(0,e.getCachedRxDocuments)(t)}var Gt="function"==typeof WeakRef?function(e){return new WeakRef(e)}:function(e){return{deref:()=>e}};var Yt=function(){function e(e,t,r){this.time=se(),this.query=e,this.count=r,this.documents=Jt(this.query.collection._docCache,t)}return e.prototype.getValue=function(e){var t=this.query.op;if("count"===t)return this.count;if("findOne"===t){var r=0===this.documents.length?null:this.documents[0];if(!r&&e)throw C("QU10",{collection:this.query.collection.name,query:this.query.mangoQuery,op:t});return r}return"findByIds"===t?this.docsMap:this.documents.slice(0)},(0,b.A)(e,[{key:"docsData",get:function(){return u(this,"docsData",this.documents.map((e=>e._data)))}},{key:"docsDataMap",get:function(){var e=new Map;return this.documents.forEach((t=>{e.set(t.primary,t._data)})),u(this,"docsDataMap",e)}},{key:"docsMap",get:function(){for(var e=new Map,t=this.documents,r=0;r"string"!=typeof e)))return r.$eq}return!1}(this.collection.schema.primaryPath,t)}var t=e.prototype;return t._setResultData=function(e){if(void 0===e)throw C("QU18",{database:this.collection.database.name,collection:this.collection.name});if("number"!=typeof e){e instanceof Map&&(e=Array.from(e.values()));var t=new Yt(this,e,e.length);this._result=t}else this._result=new Yt(this,[],e)},t._execOverDatabase=async function(){if(this._execOverDatabaseCount=this._execOverDatabaseCount+1,"count"===this.op){var e=this.getPreparedQuery(),t=await this.collection.storageInstance.count(e);if("slow"!==t.mode||this.collection.database.allowSlowCount)return t.count;throw C("QU14",{collection:this.collection,queryObj:this.mangoQuery})}if("findByIds"===this.op){var r=(0,me.ZN)(this.mangoQuery.selector)[this.collection.schema.primaryPath].$in,a=new Map,n=[];if(r.forEach((e=>{var t=this.collection._docCache.getLatestDocumentDataIfExists(e);if(t){if(!t._deleted){var r=this.collection._docCache.getCachedRxDocument(t);a.set(e,r)}}else n.push(e)})),n.length>0)(await this.collection.storageInstance.findDocumentsById(n,!1)).forEach((e=>{var t=this.collection._docCache.getCachedRxDocument(e);a.set(t.primary,t)}));return a}var i=async function(e){var t=[],r=e.collection;if(e.isFindOneByIdQuery)if(Array.isArray(e.isFindOneByIdQuery)){var a=e.isFindOneByIdQuery;if(a=a.filter((r=>{var a=e.collection._docCache.getLatestDocumentDataIfExists(r);return!a||(a._deleted||t.push(a),!1)})),a.length>0){var n=await r.storageInstance.findDocumentsById(a,!1);(0,g.Hb)(t,n)}}else{var i=e.isFindOneByIdQuery,s=e.collection._docCache.getLatestDocumentDataIfExists(i);if(!s){var o=await r.storageInstance.findDocumentsById([i],!1);o[0]&&(s=o[0])}s&&!s._deleted&&t.push(s)}else{var c=e.getPreparedQuery(),u=await r.storageInstance.query(c);t=u.documents}return t}(this);return i.then((e=>e))},t.exec=async function(e){if(e&&"findOne"!==this.op)throw C("QU9",{collection:this.collection.name,query:this.mangoQuery,op:this.op});return await ar(this),(0,me.ZN)(this._result).getValue(e)},t.toString=function(){var e=o({op:this.op,query:je(this.collection.schema.jsonSchema,this.mangoQuery),other:this.other},!0),t=JSON.stringify(e);return this.toString=()=>t,t},t.getPreparedQuery=function(){var e={rxQuery:this,mangoQuery:je(this.collection.schema.jsonSchema,this.mangoQuery)};e.mangoQuery.selector._deleted={$eq:!1},e.mangoQuery.index&&e.mangoQuery.index.unshift("_deleted"),He("prePrepareQuery",e);var t=Be(this.collection.schema.jsonSchema,e.mangoQuery);return this.getPreparedQuery=()=>t,t},t.doesDocumentDataMatch=function(e){return!e._deleted&&this.queryMatcher(e)},t.remove=async function(){var e=await this.exec();if(Array.isArray(e)){var t=await this.collection.bulkRemove(e);if(t.error.length>0)throw j(t.error[0]);return t.success}return e.remove()},t.incrementalRemove=function(){return Ae(this.asRxQuery,(e=>e.incrementalRemove()))},t.update=function(e){throw kt("update")},t.patch=function(e){return Ae(this.asRxQuery,(t=>t.patch(e)))},t.incrementalPatch=function(e){return Ae(this.asRxQuery,(t=>t.incrementalPatch(e)))},t.modify=function(e){return Ae(this.asRxQuery,(t=>t.modify(e)))},t.incrementalModify=function(e){return Ae(this.asRxQuery,(t=>t.incrementalModify(e)))},t.where=function(e){throw kt("query-builder")},t.sort=function(e){throw kt("query-builder")},t.skip=function(e){throw kt("query-builder")},t.limit=function(e){throw kt("query-builder")},(0,b.A)(e,[{key:"$",get:function(){if(!this._$){var e=this.collection.eventBulks$.pipe((0,bt.p)((e=>!e.isLocal)),(0,wt.Z)(null),(0,Bt.Z)((()=>ar(this))),(0,gt.T)((()=>this._result)),(0,xt.t)(me.bz),(0,Dt.F)(((e,t)=>!(!e||e.time!==(0,me.ZN)(t).time))),(0,bt.p)((e=>!!e)),(0,gt.T)((e=>(0,me.ZN)(e).getValue())));this._$=(0,At.h)(e,this.refCount$.pipe((0,bt.p)((()=>!1))))}return this._$}},{key:"$$",get:function(){return this.collection.database.getReactivityFactory().fromObservable(this.$,void 0,this.collection.database)}},{key:"queryMatcher",get:function(){this.collection.schema.jsonSchema;return u(this,"queryMatcher",Ne(0,je(this.collection.schema.jsonSchema,this.mangoQuery)))}},{key:"asRxQuery",get:function(){return this}}])}();function tr(e,t,r,a){He("preCreateRxQuery",{op:e,queryObj:t,collection:r,other:a});var n,i,s=new er(e,t,r,a);return s=(n=s).collection._queryCache.getByQuery(n),i=r,Zt.has(i)||(Zt.add(i),(0,ue.dY)().then((()=>(0,ue.Ve)(200))).then((()=>{i.closed||i.cacheReplacementPolicy(i,i._queryCache),Zt.delete(i)}))),s}function rr(e){var t=e.asRxQuery.collection._changeEventBuffer.getCounter();return e._latestChangeEvent>=t}async function ar(e){return e.collection.awaitBeforeReads.size>0&&await Promise.all(Array.from(e.collection.awaitBeforeReads).map((e=>e()))),!e.collection.database.closed&&!rr(e)&&(e._ensureEqualQueue=e._ensureEqualQueue.then((()=>function(e){if(e._lastEnsureEqual=se(),e.collection.database.closed||rr(e))return ue.Dr;var t=!1,r=!1;-1===e._latestChangeEvent&&(r=!0);if(!r){var a=e.asRxQuery.collection._changeEventBuffer.getFrom(e._latestChangeEvent+1);if(null===a)r=!0;else{e._latestChangeEvent=e.asRxQuery.collection._changeEventBuffer.getCounter();var n=e.asRxQuery.collection._changeEventBuffer.reduceByLastOfDoc(a);if("count"===e.op){var i=(0,me.ZN)(e._result).count,s=i;n.forEach((t=>{var r=t.previousDocumentData&&e.doesDocumentDataMatch(t.previousDocumentData),a=e.doesDocumentDataMatch(t.documentData);!r&&a&&s++,r&&!a&&s--})),s!==i&&(t=!0,e._setResultData(s))}else{var o=Lt(e,n);o.runFullQueryAgain?r=!0:o.changed&&(t=!0,e._setResultData(o.newResults))}}}if(r)return e._execOverDatabase().then((r=>(e._latestChangeEvent=e.collection._changeEventBuffer.getCounter(),"number"==typeof r?(e._result&&r===e._result.count||(t=!0,e._setResultData(r)),t):(e._result&&function(e,t,r){if(t.length!==r.length)return!1;for(var a=0,n=t.length;ae.data.name===n)),u=[];c.forEach((e=>{u.push({collectionName:e.data.name,schema:e.data.schema,isCollection:!0}),e.data.connectedStorages.forEach((e=>u.push({collectionName:e.collectionName,isCollection:!1,schema:e.schema})))}));var h=new Set;if(u=u.filter((e=>{var t=e.collectionName+"||"+e.schema.version;return!h.has(t)&&(h.add(t),!0)})),await Promise.all(u.map((async t=>{var o=await e.createStorageInstance({collectionName:t.collectionName,databaseInstanceToken:r,databaseName:a,multiInstance:i,options:{},schema:t.schema,password:s,devMode:x.isDevMode()});await o.remove(),t.isCollection&&await Ke("postRemoveRxCollection",{storage:e,databaseName:a,collectionName:n})}))),o){var l=c.map((e=>{var t=Ye(e);return t._deleted=!0,t._meta.lwt=se(),t._rev=Fe(r,e),{previous:e,document:t}}));await t.bulkWrite(l,"rx-database-remove-collection-all")}}function fr(e){if(e.closed)throw C("COL21",{collection:e.name,version:e.schema.version})}var pr=function(){function e(e){this.subs=[],this.counter=0,this.eventCounterMap=new WeakMap,this.buffer=[],this.limit=100,this.tasks=new Set,this.collection=e,this.subs.push(this.collection.eventBulks$.pipe((0,bt.p)((e=>!e.isLocal))).subscribe((e=>{this.tasks.add((()=>this._handleChangeEvents(e.events))),this.tasks.size<=1&&(0,ue.vN)().then((()=>{this.processTasks()}))})))}var t=e.prototype;return t.processTasks=function(){0!==this.tasks.size&&(Array.from(this.tasks).forEach((e=>e())),this.tasks.clear())},t._handleChangeEvents=function(e){var t=this.counter;this.counter=this.counter+e.length,e.length>this.limit?this.buffer=e.slice(-1*e.length):((0,g.Hb)(this.buffer,e),this.buffer=this.buffer.slice(-1*this.limit));for(var r=t+1,a=this.eventCounterMap,n=0;nt(e)))},t.reduceByLastOfDoc=function(e){return this.processTasks(),e.slice(0)},t.close=function(){this.tasks.clear(),this.subs.forEach((e=>e.unsubscribe()))},e}();var vr=new WeakMap;function yr(e){var t=e.schema.getDocumentPrototype(),r=function(e){var t={};return Object.entries(e.methods).forEach((e=>{let[r,a]=e;t[r]=a})),t}(e),a={};return[t,r,St].forEach((e=>{Object.getOwnPropertyNames(e).forEach((t=>{var r=Object.getOwnPropertyDescriptor(e,t),n=!0;(t.startsWith("_")||t.endsWith("_")||t.startsWith("$")||t.endsWith("$"))&&(n=!1),"function"==typeof r.value?Object.defineProperty(a,t,{get(){return r.value.bind(this)},enumerable:n,configurable:!1}):(r.enumerable=n,r.configurable=!1,r.writable&&(r.writable=!1),Object.defineProperty(a,t,r))}))})),a}function gr(e,t,r){var a=function(e,t,r){var a=new e(t,r);return He("createRxDocument",a),a}(t,e,x.deepFreezeWhenDevMode(r));return e._runHooksSync("post","create",r,a),He("postCreateRxDocument",a),a}var br={isEqual:(e,t)=>(0,pt.b)(Ge(e),Ge(t)),resolve:e=>e.realMasterState},wr=["pre","post"],Dr=["insert","save","remove","create"],xr=!1,kr=new Set,_r=function(){function e(e,t,r,a,n,i,s,o,c,u,h,l){void 0===n&&(n={}),void 0===i&&(i={}),void 0===s&&(s={}),void 0===o&&(o={}),void 0===c&&(c={}),void 0===u&&(u=zt),void 0===h&&(h={}),void 0===l&&(l=br),this.storageInstance={},this.timeouts=new Set,this.incrementalWriteQueue={},this.awaitBeforeReads=new Set,this._incrementalUpsertQueues=new Map,this.synced=!1,this.hooks={},this._subs=[],this._docCache={},this._queryCache=new Qt,this.$={},this.checkpoint$={},this._changeEventBuffer={},this.eventBulks$={},this.onClose=[],this.closed=!1,this.onRemove=[],this.database=e,this.name=t,this.schema=r,this.internalStorageInstance=a,this.instanceCreationOptions=n,this.migrationStrategies=i,this.methods=s,this.attachments=o,this.options=c,this.cacheReplacementPolicy=u,this.statics=h,this.conflictHandler=l,function(e){if(xr)return;xr=!0;var t=Object.getPrototypeOf(e);Dr.forEach((e=>{wr.map((r=>{var a=r+(0,N.Z2)(e);t[a]=function(t,a){return this.addHook(r,e,t,a)}}))}))}(this.asRxCollection),e&&(this.eventBulks$=e.eventBulks$.pipe((0,bt.p)((e=>e.collectionName===this.name)))),this.database&&kr.add(this)}var t=e.prototype;return t.prepare=async function(){if(!await de()){for(var e=0;e<10&&kr.size>16;)e++,await this.promiseWait(30);if(kr.size>16)throw C("COL23",{database:this.database.name,collection:this.name,args:{existing:Array.from(kr.values()).map((e=>({db:e.database?e.database.name:"",c:e.name})))}})}var t,r;this.storageInstance=Xe(this.database,this.internalStorageInstance,this.schema.jsonSchema),this.incrementalWriteQueue=new Ct(this.storageInstance,this.schema.primaryPath,((e,t)=>jt(this,e,t)),(e=>this._runHooks("post","save",e))),this.$=this.eventBulks$.pipe((0,Bt.Z)((e=>Rt(e)))),this.checkpoint$=this.eventBulks$.pipe((0,gt.T)((e=>e.checkpoint))),this._changeEventBuffer=(t=this.asRxCollection,new pr(t)),this._docCache=new Ut(this.schema.primaryPath,this.eventBulks$.pipe((0,bt.p)((e=>!e.isLocal)),(0,gt.T)((e=>e.events))),(e=>{var t;return r||(t=this.asRxCollection,r=i(vr,t,(()=>Pt(yr(t))))),gr(this.asRxCollection,r,e)}));var a=this.database.internalStore.changeStream().pipe((0,bt.p)((e=>{var t=this.name+"-"+this.schema.version;return!!e.events.find((e=>"collection"===e.documentData.context&&e.documentData.key===t&&"DELETE"===e.operation))}))).subscribe((async()=>{await this.close(),await Promise.all(this.onRemove.map((e=>e())))}));this._subs.push(a);var n=await this.database.storageToken,s=this.storageInstance.changeStream().subscribe((e=>{var t={id:e.id,isLocal:!1,internal:!1,collectionName:this.name,storageToken:n,events:e.events,databaseToken:this.database.token,checkpoint:e.checkpoint,context:e.context};this.database.$emit(t)}));return this._subs.push(s),ue.em},t.cleanup=function(e){throw fr(this),kt("cleanup")},t.migrationNeeded=function(){throw kt("migration-schema")},t.getMigrationState=function(){throw kt("migration-schema")},t.startMigration=function(e){return void 0===e&&(e=10),fr(this),this.getMigrationState().startMigration(e)},t.migratePromise=function(e){return void 0===e&&(e=10),this.getMigrationState().migratePromise(e)},t.insert=async function(e){fr(this);var t=await this.bulkInsert([e]),r=t.error[0];return Ve(this,e[this.schema.primaryPath],e,r),(0,me.ZN)(t.success[0])},t.insertIfNotExists=async function(e){var t=await this.bulkInsert([e]);if(t.error.length>0){var r=t.error[0];if(409===r.status){var a=r.documentInDb;return Jt(this._docCache,[a])[0]}throw r}return t.success[0]},t.bulkInsert=async function(e){if(fr(this),0===e.length)return{success:[],error:[]};var t,r=this.schema.primaryPath,a=new Set;if(this.hasHooks("pre","insert"))t=await Promise.all(e.map((e=>{var t=dr(this.schema,e);return this._runHooks("pre","insert",t).then((()=>(a.add(t[r]),{document:t})))})));else{t=new Array(e.length);for(var n=this.schema,i=0;i{var t=e.document;l.set(t[r],t)})),await Promise.all(h.success.map((e=>this._runHooks("post","insert",l.get(e.primary),e))))}return h},t.bulkRemove=async function(e){fr(this);var t,r=this.schema.primaryPath;if(0===e.length)return{success:[],error:[]};"string"==typeof e[0]?t=await this.findByIds(e).exec():(t=new Map,e.forEach((e=>t.set(e.primary,e))));var a=[],n=new Map;Array.from(t.values()).forEach((e=>{var t=e.toMutableJSON(!0);a.push(t),n.set(e.primary,t)})),await Promise.all(a.map((e=>{var r=e[this.schema.primaryPath];return this._runHooks("pre","remove",e,t.get(r))})));var i=a.map((e=>{var t=s(e);return t._deleted=!0,{previous:e,document:t}})),o=await this.storageInstance.bulkWrite(i,"rx-collection-bulk-remove"),c=rt(this.schema.primaryPath,i,o),u=[],h=c.map((e=>{var t=e[r],a=this._docCache.getCachedRxDocument(e);return u.push(a),t}));return await Promise.all(h.map((e=>this._runHooks("post","remove",n.get(e),t.get(e))))),{success:u,error:o.error}},t.bulkUpsert=async function(e){fr(this);var t=[],r=new Map;e.forEach((e=>{var a=dr(this.schema,e),n=a[this.schema.primaryPath];if(!n)throw C("COL3",{primaryPath:this.schema.primaryPath,data:a,schema:this.schema.jsonSchema});r.set(n,a),t.push(a)}));var a=await this.bulkInsert(t),i=a.success.slice(0),s=[];return await Promise.all(a.error.map((async e=>{if(409!==e.status)s.push(e);else{var t=e.documentId,a=n(r,t),o=(0,me.ZN)(e.documentInDb),c=this._docCache.getCachedRxDocuments([o])[0],u=await c.incrementalModify((()=>a));i.push(u)}}))),{error:s,success:i}},t.upsert=async function(e){fr(this);var t=await this.bulkUpsert([e]);return Ve(this.asRxCollection,e[this.schema.primaryPath],e,t.error[0]),t.success[0]},t.incrementalUpsert=function(e){fr(this);var t=dr(this.schema,e),r=t[this.schema.primaryPath];if(!r)throw C("COL4",{data:e});var a=this._incrementalUpsertQueues.get(r);return a||(a=ue.em),a=a.then((()=>function(e,t,r){var a=e._docCache.getLatestDocumentDataIfExists(t);if(a)return Promise.resolve({doc:e._docCache.getCachedRxDocuments([a])[0],inserted:!1});return e.findOne(t).exec().then((t=>t?{doc:t,inserted:!1}:e.insert(r).then((e=>({doc:e,inserted:!0})))))}(this,r,t))).then((e=>e.inserted?e.doc:function(e,t){return e.incrementalModify((e=>t))}(e.doc,t))),this._incrementalUpsertQueues.set(r,a),a},t.find=function(e){return fr(this),He("prePrepareRxQuery",{op:"find",queryObj:e,collection:this}),e||(e={selector:{}}),tr("find",e,this)},t.findOne=function(e){var t;if(fr(this),He("prePrepareRxQuery",{op:"findOne",queryObj:e,collection:this}),"string"==typeof e)t=tr("findOne",{selector:{[this.schema.primaryPath]:e},limit:1},this);else{if(e||(e={selector:{}}),e.limit)throw C("QU6");(e=s(e)).limit=1,t=tr("findOne",e,this)}return t},t.count=function(e){return fr(this),e||(e={selector:{}}),tr("count",e,this)},t.findByIds=function(e){return fr(this),tr("findByIds",{selector:{[this.schema.primaryPath]:{$in:e.slice(0)}}},this)},t.exportJSON=function(){throw kt("json-dump")},t.importJSON=function(e){throw kt("json-dump")},t.insertCRDT=function(e){throw kt("crdt")},t.addPipeline=function(e){throw kt("pipeline")},t.addHook=function(e,t,r,a){if(void 0===a&&(a=!1),"function"!=typeof r)throw O("COL7",{key:t,when:e});if(!wr.includes(e))throw O("COL8",{key:t,when:e});if(!Dr.includes(t))throw C("COL9",{key:t});if("post"===e&&"create"===t&&!0===a)throw C("COL10",{when:e,key:t,parallel:a});var n=r.bind(this),i=a?"parallel":"series";this.hooks[t]=this.hooks[t]||{},this.hooks[t][e]=this.hooks[t][e]||{series:[],parallel:[]},this.hooks[t][e][i].push(n)},t.getHooks=function(e,t){return this.hooks[t]&&this.hooks[t][e]?this.hooks[t][e]:{series:[],parallel:[]}},t.hasHooks=function(e,t){if(!this.hooks[t]||!this.hooks[t][e])return!1;var r=this.getHooks(e,t);return!!r&&(r.series.length>0||r.parallel.length>0)},t._runHooks=function(e,t,r,a){var n=this.getHooks(e,t);if(!n)return ue.em;var i=n.series.map((e=>()=>e(r,a)));return(0,ue.h$)(i).then((()=>Promise.all(n.parallel.map((e=>e(r,a))))))},t._runHooksSync=function(e,t,r,a){if(this.hasHooks(e,t)){var n=this.getHooks(e,t);n&&n.series.forEach((e=>e(r,a)))}},t.promiseWait=function(e){return new Promise((t=>{var r=setTimeout((()=>{this.timeouts.delete(r),t()}),e);this.timeouts.add(r)}))},t.close=async function(){return this.closed?ue.Dr:(kr.delete(this),await Promise.all(this.onClose.map((e=>e()))),this.closed=!0,Array.from(this.timeouts).forEach((e=>clearTimeout(e))),this._changeEventBuffer&&this._changeEventBuffer.close(),this.database.requestIdlePromise().then((()=>this.storageInstance.close())).then((()=>(this._subs.forEach((e=>e.unsubscribe())),delete this.database.collections[this.name],Ke("postCloseRxCollection",this).then((()=>!0))))))},t.remove=async function(){await this.close(),await Promise.all(this.onRemove.map((e=>e()))),await mr(this.database.storage,this.database.internalStore,this.database.token,this.database.name,this.name,this.database.multiInstance,this.database.password,this.database.hashFunction)},(0,b.A)(e,[{key:"insert$",get:function(){return this.$.pipe((0,bt.p)((e=>"INSERT"===e.operation)))}},{key:"update$",get:function(){return this.$.pipe((0,bt.p)((e=>"UPDATE"===e.operation)))}},{key:"remove$",get:function(){return this.$.pipe((0,bt.p)((e=>"DELETE"===e.operation)))}},{key:"asRxCollection",get:function(){return this}}])}();var Ir=r(7635),Er=r(5525),Rr=new Set,Cr=function(){function e(e,t,r,a,n,i,s,o,c,u,h,l,d){void 0===s&&(s=!1),void 0===o&&(o={}),this.idleQueue=new Ir.G,this.rxdbVersion=mt,this.storageInstances=new Set,this._subs=[],this.startupErrors=[],this.onClose=[],this.closed=!1,this.collections={},this.states={},this.eventBulks$=new ne.B,this.observable$=this.eventBulks$.pipe((0,Bt.Z)((e=>Rt(e)))),this.storageToken=ue.Dr,this.storageTokenDocument=ue.Dr,this.emittedEventBulkIds=new Er.p4(6e4),this.name=e,this.token=t,this.storage=r,this.instanceCreationOptions=a,this.password=n,this.multiInstance=i,this.eventReduce=s,this.options=o,this.internalStore=c,this.hashFunction=u,this.cleanupPolicy=h,this.allowSlowCount=l,this.reactivity=d,"pseudoInstance"!==this.name&&(this.internalStore=Xe(this.asRxDatabase,c,sr),this.storageTokenDocument=async function(e){var t=(0,N.zs)(10),r=e.password?await e.hashFunction(JSON.stringify(e.password)):void 0,a=[{document:{id:hr,context:ir,key:ur,data:{rxdbVersion:e.rxdbVersion,token:t,instanceToken:e.token,passwordHash:r},_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}}}],n=await e.internalStore.bulkWrite(a,"internal-add-storage-token");if(!n.error[0])return rt("id",a,n)[0];var i=(0,me.ZN)(n.error[0]);if(i.isError&&S(i)){var s=i;if(!function(e,t){if(!e)return!1;var r=e.split(".")[0],a=t.split(".")[0];return"15"===r&&"16"===a||r===a}(s.documentInDb.data.rxdbVersion,e.rxdbVersion))throw C("DM5",{args:{database:e.name,databaseStateVersion:s.documentInDb.data.rxdbVersion,codeVersion:e.rxdbVersion}});if(r&&r!==s.documentInDb.data.passwordHash)throw C("DB1",{passwordHash:r,existingPasswordHash:s.documentInDb.data.passwordHash});var o=s.documentInDb;return(0,me.ZN)(o)}throw i}(this.asRxDatabase).catch((e=>this.startupErrors.push(e))),this.storageToken=this.storageTokenDocument.then((e=>e.data.token)).catch((e=>this.startupErrors.push(e))))}var t=e.prototype;return t.getReactivityFactory=function(){if(!this.reactivity)throw C("DB14",{database:this.name});return this.reactivity},t.$emit=function(e){this.emittedEventBulkIds.has(e.id)||(this.emittedEventBulkIds.add(e.id),this.eventBulks$.next(e))},t.removeCollectionDoc=async function(e,t){var r=await Ze(this.internalStore,or(lr(e,t),nr));if(!r)throw C("SNH",{name:e,schema:t});var a=Ye(r);a._deleted=!0,await this.internalStore.bulkWrite([{document:a,previous:r}],"rx-database-remove-collection")},t.addCollections=async function(e){var t={},r={},a=[],n={};await Promise.all(Object.entries(e).map((async e=>{let[i,o]=e;var c=i,u=o.schema;t[c]=u;var h=yt(u,this.hashFunction);if(r[c]=h,this.collections[i])throw C("DB3",{name:i});var l=lr(i,u),d={id:or(l,nr),key:l,context:nr,data:{name:c,schemaHash:await h.hash,schema:h.jsonSchema,version:h.version,connectedStorages:[]},_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}};a.push({document:d});var m=Object.assign({},o,{name:c,schema:h,database:this}),f=s(o);f.database=this,f.name=i,He("preCreateRxCollection",f),m.conflictHandler=f.conflictHandler,n[c]=m})));var i=await this.internalStore.bulkWrite(a,"rx-database-add-collection");await async function(e){if(await e.storageToken,e.startupErrors[0])throw e.startupErrors[0]}(this),await Promise.all(i.error.map((async e=>{if(409!==e.status)throw C("DB12",{database:this.name,writeError:e});var a=(0,me.ZN)(e.documentInDb),n=a.data.name,i=r[n];if(a.data.schemaHash!==await i.hash)throw C("DB6",{database:this.name,collection:n,previousSchemaHash:a.data.schemaHash,schemaHash:await i.hash,previousSchema:a.data.schema,schema:(0,me.ZN)(t[n])})})));var o={};return await Promise.all(Object.keys(e).map((async e=>{var t=n[e],r=await function(e){let{database:t,name:r,schema:a,instanceCreationOptions:n={},migrationStrategies:i={},autoMigrate:s=!0,statics:o={},methods:c={},attachments:u={},options:h={},localDocuments:l=!1,cacheReplacementPolicy:d=zt,conflictHandler:m=br}=e;var f={databaseInstanceToken:t.token,databaseName:t.name,collectionName:r,schema:a.jsonSchema,options:n,multiInstance:t.multiInstance,password:t.password,devMode:x.isDevMode()};return He("preCreateRxStorageInstance",f),async function(e,t){return t.multiInstance=e.multiInstance,await e.storage.createStorageInstance(t)}(t,f).then((e=>{var f=new _r(t,r,a,e,n,i,c,u,h,d,o,m);return f.prepare().then((()=>{Object.entries(o).forEach((e=>{let[t,r]=e;Object.defineProperty(f,t,{get:()=>r.bind(f)})}));var e=ue.em;return s&&0!==f.schema.version&&(e=f.migratePromise()),e})).then((()=>(He("createRxCollection",{collection:f,creator:{name:r,schema:a,storageInstance:e,instanceCreationOptions:n,migrationStrategies:i,methods:c,attachments:u,options:h,cacheReplacementPolicy:d,localDocuments:l,statics:o}}),f))).catch((t=>(kr.delete(f),e.close().then((()=>Promise.reject(t))))))}))}(t);o[e]=r,this.collections[e]=r,this[e]||Object.defineProperty(this,e,{get:()=>this.collections[e]})}))),o},t.lockedRun=function(e){return this.idleQueue.wrapCall(e)},t.requestIdlePromise=function(){return this.idleQueue.requestIdlePromise()},t.exportJSON=function(e){throw kt("json-dump")},t.addState=function(e){throw kt("state")},t.importJSON=function(e){throw kt("json-dump")},t.backup=function(e){throw kt("backup")},t.leaderElector=function(){throw kt("leader-election")},t.isLeader=function(){throw kt("leader-election")},t.waitForLeadership=function(){throw kt("leader-election")},t.migrationStates=function(){throw kt("migration-schema")},t.close=async function(){return this.closed?ue.Dr:(this.closed=!0,await Ke("preCloseRxDatabase",this),this.eventBulks$.complete(),this._subs.map((e=>e.unsubscribe())),"pseudoInstance"===this.name?ue.Dr:this.requestIdlePromise().then((()=>Promise.all(this.onClose.map((e=>e()))))).then((()=>Promise.all(Object.keys(this.collections).map((e=>this.collections[e])).map((e=>e.close()))))).then((()=>this.internalStore.close())).then((()=>Rr.delete(this.storage.name+"|"+this.name))).then((()=>!0)))},t.remove=function(){return this.close().then((()=>async function(e,t,r,a){void 0===r&&(r=!0);var n=(0,N.zs)(10),i=await Or(n,t,e,{},r,a),s=await cr(i),o=new Set;s.forEach((e=>o.add(e.data.name)));var c=Array.from(o);return await Promise.all(c.map((s=>mr(t,i,n,e,s,r,a)))),await Ke("postRemoveRxDatabase",{databaseName:e,storage:t}),await i.remove(),c}(this.name,this.storage,this.multiInstance,this.password)))},(0,b.A)(e,[{key:"$",get:function(){return this.observable$}},{key:"asRxDatabase",get:function(){return this}}])}();async function Or(e,t,r,a,n,i){return await t.createStorageInstance({databaseInstanceToken:e,databaseName:r,collectionName:ze,schema:sr,options:a,multiInstance:n,password:i,devMode:x.isDevMode()})}function Sr(e){let{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i=!0,eventReduce:s=!0,ignoreDuplicate:o=!1,options:c={},cleanupPolicy:u,allowSlowCount:h=!1,localDocuments:l=!1,hashFunction:d=ce.V0,reactivity:m}=e;if(He("preCreateRxDatabase",{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i,eventReduce:s,ignoreDuplicate:o,options:c,localDocuments:l}),o){if(!x.isDevMode())throw C("DB9",{database:a})}else!function(e,t){var r=t.name+"|"+e;if(Rr.has(r))throw C("DB8",{name:e,storage:t.name,link:"https://rxdb.info/rx-database.html#ignoreduplicate"})}(a,t);Rr.add(t.name+"|"+a);var f=(0,N.zs)(10);return Or(f,t,a,r,i,n).catch((e=>{throw Rr.delete(t.name+"|"+a),e})).then((e=>{var p=new Cr(a,f,t,r,n,i,s,c,e,d,u,h,m);return Ke("createRxDatabase",{database:p,creator:{storage:t,instanceCreationOptions:r,name:a,password:n,multiInstance:i,eventReduce:s,ignoreDuplicate:o,options:c,localDocuments:l}}).then((()=>p))}))}var Pr={RxSchema:vt.prototype,RxDocument:St,RxQuery:er.prototype,RxCollection:_r.prototype,RxDatabase:Cr.prototype},jr=new Set,$r=new Set;var Nr=function(e){function t(t,r,a){var n;return(n=e.call(this,null,r)||this).id=t,n.parent=a,n}return(0,w.A)(t,e),t}(Pt()),Ar={get isLocal(){return!0},get allAttachments$(){throw C("LD1",{document:this})},get primaryPath(){return"id"},get primary(){return this.id},get $(){var e=n(Lr,this.parent),t=this.primary;return this.parent.eventBulks$.pipe((0,bt.p)((e=>!!e.isLocal)),(0,gt.T)((e=>e.events.find((e=>e.documentId===t)))),(0,bt.p)((e=>!!e)),(0,gt.T)((e=>_t((0,me.ZN)(e)))),(0,wt.Z)(e.docCache.getLatestDocumentData(this.primary)),(0,Dt.F)(((e,t)=>e._rev===t._rev)),(0,gt.T)((t=>e.docCache.getCachedRxDocument(t))),(0,xt.t)(me.bz))},get $$(){var e=this,t=qr(e);return t.getReactivityFactory().fromObservable(e.$,e.getLatest()._data,t)},get deleted$$(){var e=this,t=qr(e);return t.getReactivityFactory().fromObservable(e.deleted$,e.getLatest().deleted,t)},getLatest(){var e=n(Lr,this.parent),t=e.docCache.getLatestDocumentData(this.primary);return e.docCache.getCachedRxDocument(t)},get(e){if(e="data."+e,this._data){if("string"!=typeof e)throw O("LD2",{objPath:e});var t=v(this._data,e);return t=x.deepFreezeWhenDevMode(t)}},get$(e){if(e="data."+e,x.isDevMode()){if(e.includes(".item."))throw C("LD3",{objPath:e});if(e===this.primaryPath)throw C("LD4")}return this.$.pipe((0,gt.T)((e=>e._data)),(0,gt.T)((t=>v(t,e))),(0,Dt.F)())},get$$(e){var t=qr(this);return t.getReactivityFactory().fromObservable(this.get$(e),this.getLatest().get(e),t)},async incrementalModify(e){var t=await Fr(this.parent);return t.incrementalWriteQueue.addWrite(this._data,(async t=>(t.data=await e(t.data,this),t))).then((e=>t.docCache.getCachedRxDocument(e)))},incrementalPatch(e){return this.incrementalModify((t=>(Object.entries(e).forEach((e=>{let[r,a]=e;t[r]=a})),t)))},async _saveData(e){var t=await Fr(this.parent),r=this._data;e.id=this.id;var a=[{previous:r,document:e}];return t.storageInstance.bulkWrite(a,"local-document-save-data").then((t=>{if(t.error[0])throw t.error[0];var r=rt(this.collection.schema.primaryPath,a,t)[0];(e=s(e))._rev=r._rev}))},async remove(){var e=await Fr(this.parent),t=s(this._data);return t._deleted=!0,Ue(e.storageInstance,{previous:this._data,document:t},"local-document-remove").then((t=>e.docCache.getCachedRxDocument(t)))}},Br=!1,Mr=()=>{if(!Br){Br=!0;var e=St;Object.getOwnPropertyNames(e).forEach((t=>{if(!Object.getOwnPropertyDescriptor(Ar,t)){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(Ar,t,r)}}));["populate","update","putAttachment","getAttachment","allAttachments"].forEach((e=>Ar[e]=(e=>()=>{throw C("LD6",{functionName:e})})(e)))}};function qr(e){var t=e.parent;return t instanceof Cr?t:t.database}var Tr=new WeakMap,Lr=new WeakMap;function Qr(e){var t=e.database?e.database:e,r=e.database?e.name:"",a=(async()=>{var a=await Wr(t.token,t.storage,t.name,r,t.instanceCreationOptions,t.multiInstance);a=Xe(t,a,Zr);var n=new Ut("id",t.eventBulks$.pipe((0,bt.p)((e=>{var t=!1;return(""===r&&!e.collectionName||""!==r&&e.collectionName===r)&&(t=!0),t&&e.isLocal})),(0,gt.T)((e=>e.events))),(t=>function(e,t){Mr();var r=new Nr(e.id,e,t);return Object.setPrototypeOf(r,Ar),r.prototype=Ar,r}(t,e))),i=new Ct(a,"id",(()=>{}),(()=>{})),s=await t.storageToken,o=a.changeStream().subscribe((r=>{for(var a=new Array(r.events.length),n=r.events,i=e.database?e.name:void 0,o=0;oe.storageInstance.close()))}async function Kr(e,t,r){var a=(0,N.zs)(10),n=await Wr(a,e,t,r,{},!1);await n.remove()}function zr(e){return"plugin-local-documents-"+e}var Zr=q({title:"RxLocalDocument",version:0,primaryKey:"id",type:"object",properties:{id:{type:"string",maxLength:128},data:{type:"object",additionalProperties:!0}},required:["id","data"]});async function Ur(e,t){var r=await Fr(this),a={id:e,data:t,_deleted:!1,_meta:{lwt:1},_rev:"",_attachments:{}};return Ue(r.storageInstance,{document:a},"local-document-insert").then((e=>r.docCache.getCachedRxDocument(e)))}function Vr(e,t){return this.getLocal(e).then((r=>r?r.incrementalModify((()=>t)):this.insertLocal(e,t)))}async function Jr(e){var t=await Fr(this),r=t.docCache,a=r.getLatestDocumentDataIfExists(e);return a?Promise.resolve(r.getCachedRxDocument(a)):Ze(t.storageInstance,e).then((e=>e?t.docCache.getCachedRxDocument(e):null))}function Gr(e){return this.$.pipe((0,wt.Z)(null),(0,Bt.Z)((async t=>t?{changeEvent:t}:{doc:await this.getLocal(e)})),(0,Bt.Z)((async t=>{if(t.changeEvent){var r=t.changeEvent;return r.isLocal&&r.documentId===e?{use:!0,doc:await this.getLocal(e)}:{use:!1}}return{use:!0,doc:t.doc}})),(0,bt.p)((e=>e.use)),(0,gt.T)((e=>e.doc)))}var Yr={name:"local-documents",rxdb:!0,prototypes:{RxCollection:e=>{e.insertLocal=Ur,e.upsertLocal=Vr,e.getLocal=Jr,e.getLocal$=Gr},RxDatabase:e=>{e.insertLocal=Ur,e.upsertLocal=Vr,e.getLocal=Jr,e.getLocal$=Gr}},hooks:{createRxDatabase:{before:e=>{e.creator.localDocuments&&Qr(e.database)}},createRxCollection:{before:e=>{e.creator.localDocuments&&Qr(e.collection)}},preCloseRxDatabase:{after:e=>Hr(e)},postCloseRxCollection:{after:e=>Hr(e)},postRemoveRxDatabase:{after:e=>Kr(e.storage,e.databaseName,"")},postRemoveRxCollection:{after:e=>Kr(e.storage,e.databaseName,e.collectionName)}},overwritable:{}};let Xr;function ea(){return"undefined"!=typeof window&&window.indexedDB}function ta(){return Xr||(Xr=(async()=>{!function(e){if(He("preAddRxPlugin",{plugin:e,plugins:jr}),!jr.has(e)){if($r.has(e.name))throw C("PL3",{name:e.name,plugin:e});if(jr.add(e),$r.add(e.name),!e.rxdb)throw O("PL1",{plugin:e});e.init&&e.init(),e.prototypes&&Object.entries(e.prototypes).forEach((e=>{let[t,r]=e;return r(Pr[t])})),e.overwritable&&Object.assign(x,e.overwritable),e.hooks&&Object.entries(e.hooks).forEach((e=>{let[t,r]=e;r.after&&We[t].push(r.after),r.before&&We[t].unshift(r.before)}))}}(Yr);var e;return await Sr({name:"rxdb-landing-v4",localDocuments:!0,storage:(void 0===e&&(e={}),new ft(e))})})()),Xr}},8289:(e,t,r)=>{function a(){return new Promise((e=>setTimeout(e,0)))}function n(e){return void 0===e&&(e=0),new Promise((t=>setTimeout(t,e)))}r.d(t,{$A:()=>s,Dr:()=>i,ND:()=>n,Ve:()=>h,dY:()=>a,em:()=>o,h$:()=>l,vN:()=>c});Promise.resolve(!0);var i=Promise.resolve(!1),s=Promise.resolve(null),o=Promise.resolve();function c(e){return void 0===e&&(e=1e4),"function"==typeof requestIdleCallback?new Promise((t=>{requestIdleCallback((()=>t()),{timeout:e})})):n(0)}var u=o;function h(e){return void 0===e&&(e=void 0),u=u.then((()=>c(e)))}function l(e,t){return e.reduce(((e,t)=>e.then(t)),Promise.resolve(t))}},8653:(e,t,r)=>{function a(e){return e[e.length-1]}function n(e){return Array.isArray(e)?e.slice(0):[e]}function i(e){return Array.isArray(e)}function s(e,t){var r=0,a=-1;for(var n of e){if(!t(n,a+=1))break;r+=1}return r}function o(e,t){var r=t.length;if(0!==r){var a=e.length;e.length=a+t.length;for(var n=0;nn,Hb:()=>o,Sd:()=>s,dG:()=>a,jw:()=>c,k_:()=>i})}}]); \ No newline at end of file diff --git a/docs/assets/js/a406dc27.3b328d44.js b/docs/assets/js/a406dc27.3b328d44.js deleted file mode 100644 index 7383d6bff04..00000000000 --- a/docs/assets/js/a406dc27.3b328d44.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[1500],{2774:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"migration-storage","title":"Migration Storage","description":"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:","source":"@site/docs/migration-storage.md","sourceDirName":".","slug":"/migration-storage.html","permalink":"/migration-storage.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Migration Storage","slug":"migration-storage.html"},"sidebar":"tutorialSidebar","previous":{"title":"Schema Migration","permalink":"/migration-schema.html"},"next":{"title":"Attachments","permalink":"/rx-attachment.html"}}');var t=a(4848),i=a(8453);const o={title:"Migration Storage",slug:"migration-storage.html"},s="Storage Migration",d={},l=[{value:"Usage",id:"usage",level:2},{value:"Migrate from a previous RxDB major version",id:"migrate-from-a-previous-rxdb-major-version",level:2},{value:"Disable Version Check on RxDB Premium \ud83d\udc51",id:"disable-version-check-on-rxdb-premium-",level:2}];function m(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"storage-migration",children:"Storage Migration"})}),"\n",(0,t.jsx)(n.p,{children:"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You want to migration from one ",(0,t.jsx)(n.a,{href:"/rx-storage.html",children:"RxStorage"})," to another one."]}),"\n",(0,t.jsx)(n.li,{children:"You want to migrate to a new major RxDB version while keeping the previous saved data. This function only works from the previous major version upwards. Do not use it to migrate like rxdb v9 to v14."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The storage migration ",(0,t.jsx)(n.strong,{children:"drops deleted documents"})," and filters them out during the migration."]}),"\n",(0,t.jsxs)(n.admonition,{title:"Do never change the schema while doing a storage migration",type:"warning",children:[(0,t.jsx)(n.p,{children:"When you migrate between storages, you might want to change the schema in the same process. You should never do that because it will lead to problems afterwards and might make your database in usable."}),(0,t.jsxs)(n.p,{children:["When you also want to change your schema, first run the storage migration and afterwards run a normal ",(0,t.jsx)(n.a,{href:"/migration-schema.html",children:"schema migration"}),"."]})]}),"\n",(0,t.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.p,{children:["Lets say you want to migrate from ",(0,t.jsx)(n.a,{href:"/rx-storage-dexie.html",children:"Dexie.js"})," RxStorage to ",(0,t.jsx)(n.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import { migrateStorage } from 'rxdb/plugins/migration-storage';\nimport { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';\nimport { getRxStorageDexie } from 'rxdb-old/plugins/storage-dexie';\n\n// create the new RxDatabase\nconst db = await createRxDatabase({\n name: dbLocation,\n storage: getRxStorageDexie(),\n multiInstance: false\n});\n\nawait migrateStorage({\n database: db as any,\n /**\n * Name of the old database,\n * using the storage migration requires that the\n * new database has a different name.\n */\n oldDatabaseName: 'myOldDatabaseName',\n oldStorage: getRxStorageIndexedDB(), // RxStorage of the old database\n batchSize: 500, // batch size\n parallel: false, // <- true if it should migrate all collections in parallel. False (default) if should migrate in serial\n afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {\n console.log('storage migration: batch processed');\n }\n});\n"})}),"\n",(0,t.jsx)(n.h2,{id:"migrate-from-a-previous-rxdb-major-version",children:"Migrate from a previous RxDB major version"}),"\n",(0,t.jsxs)(n.p,{children:["To migrate from a previous RxDB major version, you have to install the 'old' RxDB in the ",(0,t.jsx)(n.code,{children:"package.json"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "dependencies": {\n "rxdb-old": "npm:rxdb@14.17.1",\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"The you can run the migration by providing the old storage:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"/* ... */\nimport { migrateStorage } from 'rxdb/plugins/migration-storage';\nimport { getRxStorageDexie } from 'rxdb-old/plugins/storage-dexie'; // <- import from the old RxDB version\n\nawait migrateStorage({\n database: db as any,\n /**\n * Name of the old database,\n * using the storage migration requires that the\n * new database has a different name.\n */\n oldDatabaseName: 'myOldDatabaseName',\n oldStorage: getRxStorageDexie(), // RxStorage of the old database\n batchSize: 500, // batch size\n parallel: false,\n afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {\n console.log('storage migration: batch processed');\n }\n});\n/* ... */\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"disable-version-check-on-rxdb-premium-",children:["Disable Version Check on ",(0,t.jsx)(n.a,{href:"/premium/",children:"RxDB Premium \ud83d\udc51"})]}),"\n",(0,t.jsxs)(n.p,{children:["RxDB Premium has a check in place that ensures that you do not accidentally use the wrong RxDB core and \ud83d\udc51 Premium version together which could break your database state.\nThis can be a problem during migrations where you have multiple versions of RxDB in use and it will throw the error ",(0,t.jsx)(n.code,{children:"Version mismatch detected"}),".\nYou can disable that check by importing and running the ",(0,t.jsx)(n.code,{children:"disableVersionCheck()"})," function from RxDB Premium."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"// RxDB Premium v15 or newer:\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/plugins/shared';\ndisableVersionCheck();\n\n\n// RxDB Premium v14:\n\n// for esm\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/dist/es/shared/version-check.js';\ndisableVersionCheck();\n\n// for cjs\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/dist/lib/shared/version-check.js';\ndisableVersionCheck();\n\n\n\n\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(m,{...e})}):m(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>s});var r=a(6540);const t={},i=r.createContext(t);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/a406dc27.9679575b.js b/docs/assets/js/a406dc27.9679575b.js new file mode 100644 index 00000000000..ecb00f06c08 --- /dev/null +++ b/docs/assets/js/a406dc27.9679575b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[1500],{2774:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"migration-storage","title":"Migration Storage","description":"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:","source":"@site/docs/migration-storage.md","sourceDirName":".","slug":"/migration-storage.html","permalink":"/migration-storage.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Migration Storage","slug":"migration-storage.html"},"sidebar":"tutorialSidebar","previous":{"title":"Schema Migration","permalink":"/migration-schema.html"},"next":{"title":"Attachments","permalink":"/rx-attachment.html"}}');var t=a(4848),i=a(8453);const o={title:"Migration Storage",slug:"migration-storage.html"},s="Storage Migration",d={},l=[{value:"Usage",id:"usage",level:2},{value:"Migrate from a previous RxDB major version",id:"migrate-from-a-previous-rxdb-major-version",level:2},{value:"Disable Version Check on RxDB Premium \ud83d\udc51",id:"disable-version-check-on-rxdb-premium-",level:2}];function m(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"storage-migration",children:"Storage Migration"})}),"\n",(0,t.jsx)(n.p,{children:"The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You want to migrate from one ",(0,t.jsx)(n.a,{href:"/rx-storage.html",children:"RxStorage"})," to another one."]}),"\n",(0,t.jsx)(n.li,{children:"You want to migrate to a new major RxDB version while keeping the previous saved data. This function only works from the previous major version upwards. Do not use it to migrate like rxdb v9 to v14."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The storage migration ",(0,t.jsx)(n.strong,{children:"drops deleted documents"})," and filters them out during the migration."]}),"\n",(0,t.jsxs)(n.admonition,{title:"Do never change the schema while doing a storage migration",type:"warning",children:[(0,t.jsx)(n.p,{children:"When you migrate between storages, you might want to change the schema in the same process. You should never do that because it will lead to problems afterwards and might make your database unusable."}),(0,t.jsxs)(n.p,{children:["When you also want to change your schema, first run the storage migration and afterwards run a normal ",(0,t.jsx)(n.a,{href:"/migration-schema.html",children:"schema migration"}),"."]})]}),"\n",(0,t.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.p,{children:["Lets say you want to migrate from ",(0,t.jsx)(n.a,{href:"/rx-storage-dexie.html",children:"Dexie.js"})," RxStorage to ",(0,t.jsx)(n.a,{href:"/rx-storage-indexeddb.html",children:"IndexedDB"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import { migrateStorage } from 'rxdb/plugins/migration-storage';\nimport { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';\nimport { getRxStorageDexie } from 'rxdb-old/plugins/storage-dexie';\n\n// create the new RxDatabase\nconst db = await createRxDatabase({\n name: dbLocation,\n storage: getRxStorageIndexedDB(),\n multiInstance: false\n});\n\nawait migrateStorage({\n database: db as any,\n /**\n * Name of the old database,\n * using the storage migration requires that the\n * new database has a different name.\n */\n oldDatabaseName: 'myOldDatabaseName',\n oldStorage: getRxStorageDexie(), // RxStorage of the old database\n batchSize: 500, // batch size\n parallel: false, // <- true if it should migrate all collections in parallel. False (default) if should migrate in serial\n afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {\n console.log('storage migration: batch processed');\n }\n});\n"})}),"\n",(0,t.jsx)(n.h2,{id:"migrate-from-a-previous-rxdb-major-version",children:"Migrate from a previous RxDB major version"}),"\n",(0,t.jsxs)(n.p,{children:["To migrate from a previous RxDB major version, you have to install the 'old' RxDB in the ",(0,t.jsx)(n.code,{children:"package.json"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "dependencies": {\n "rxdb-old": "npm:rxdb@14.17.1",\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"The you can run the migration by providing the old storage:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"/* ... */\nimport { migrateStorage } from 'rxdb/plugins/migration-storage';\nimport { getRxStorageDexie } from 'rxdb-old/plugins/storage-dexie'; // <- import from the old RxDB version\n\nawait migrateStorage({\n database: db as any,\n /**\n * Name of the old database,\n * using the storage migration requires that the\n * new database has a different name.\n */\n oldDatabaseName: 'myOldDatabaseName',\n oldStorage: getRxStorageDexie(), // RxStorage of the old database\n batchSize: 500, // batch size\n parallel: false,\n afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {\n console.log('storage migration: batch processed');\n }\n});\n/* ... */\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"disable-version-check-on-rxdb-premium-",children:["Disable Version Check on ",(0,t.jsx)(n.a,{href:"/premium/",children:"RxDB Premium \ud83d\udc51"})]}),"\n",(0,t.jsxs)(n.p,{children:["RxDB Premium has a check in place that ensures that you do not accidentally use the wrong RxDB core and \ud83d\udc51 Premium version together which could break your database state.\nThis can be a problem during migrations where you have multiple versions of RxDB in use and it will throw the error ",(0,t.jsx)(n.code,{children:"Version mismatch detected"}),".\nYou can disable that check by importing and running the ",(0,t.jsx)(n.code,{children:"disableVersionCheck()"})," function from RxDB Premium."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"// RxDB Premium v15 or newer:\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/plugins/shared';\ndisableVersionCheck();\n\n\n// RxDB Premium v14:\n\n// for esm\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/dist/es/shared/version-check.js';\ndisableVersionCheck();\n\n// for cjs\nimport {\n disableVersionCheck\n} from 'rxdb-premium-old/dist/lib/shared/version-check.js';\ndisableVersionCheck();\n\n\n\n\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(m,{...e})}):m(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>s});var r=a(6540);const t={},i=r.createContext(t);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/a94703ab.7879224d.js b/docs/assets/js/a94703ab.c4ec9661.js similarity index 66% rename from docs/assets/js/a94703ab.7879224d.js rename to docs/assets/js/a94703ab.c4ec9661.js index 4f10dbd863e..be7b7be40ba 100644 --- a/docs/assets/js/a94703ab.7879224d.js +++ b/docs/assets/js/a94703ab.c4ec9661.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[9048],{1841:(e,t,n)=>{n.r(t),n.d(t,{default:()=>pe});var a=n(6540),i=n(4164),s=n(1769),o=n(204),l=n(102),r=n(2306),c=n(539),d=n(5627),u=n(7685);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var m=n(4848);function b(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,i]=(0,a.useState)(!1),s=(0,a.useRef)(!1),{startScroll:o,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const o=n?.scrollY;o&&(s.current?s.current=!1:a>=o?(l(),i(!1)):a{e.location.hash&&(s.current=!0,i(!1))})),{shown:n,scrollToTop:()=>o(0)}}({threshold:300});return(0,m.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,i.A)("clean-btn",o.G.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var p=n(4924),x=n(6347),j=n(6682),f=n(3115),v=n(8173);function _(e){return(0,m.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,m.jsxs)("g",{fill:"#7a7a7a",children:[(0,m.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,m.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const g="collapseSidebarButton_PEFL",A="collapseSidebarButtonIcon_kv0_";function C(e){let{onClick:t}=e;return(0,m.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,i.A)("button button--secondary button--outline",g),onClick:t,children:(0,m.jsx)(_,{className:A})})}var k=n(3380),S=n(6849);const T=Symbol("EmptyContext"),N=a.createContext(T);function I(e){let{children:t}=e;const[n,i]=(0,a.useState)(null),s=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:i})),[n]);return(0,m.jsx)(N.Provider,{value:s,children:t})}var y=n(3535),B=n(214),w=n(6289),L=n(9136);function M(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,m.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:s,level:r,index:c,...d}=e;const{items:u,label:h,collapsible:b,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:j}}}=(0,f.p)(),v=function(e){const t=(0,L.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,s),g=(0,B.ys)(x,s),{collapsed:A,setCollapsed:C}=(0,y.u)({initialState:()=>!!b&&(!_&&t.collapsed)}),{expandedItem:k,setExpandedItem:I}=function(){const e=(0,a.useContext)(N);if(e===T)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),E=function(e){void 0===e&&(e=!A),I(e?null:c),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:i}=e;const s=(0,S.ZC)(t);(0,a.useEffect)((()=>{t&&!s&&n&&i(!1)}),[t,s,n,i])}({isActive:_,collapsed:A,updateCollapsed:E}),(0,a.useEffect)((()=>{b&&null!=k&&k!==c&&j&&C(!0)}),[b,k,c,C,j]),(0,m.jsxs)("li",{className:(0,i.A)(o.G.docs.docSidebarItemCategory,o.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":A},p),children:[(0,m.jsxs)("div",{className:(0,i.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":g}),children:[(0,m.jsx)(w.A,{className:(0,i.A)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!x&&b,"menu__link--active":_}),onClick:b?e=>{n?.(t),x?E(!1):(e.preventDefault(),E())}:()=>{n?.(t)},"aria-current":g?"page":void 0,role:b&&!x?"button":void 0,"aria-expanded":b&&!x?!A:void 0,href:b?v??"#":v,...d,children:h}),x&&b&&(0,m.jsx)(M,{collapsed:A,categoryLabel:h,onClick:e=>{e.preventDefault(),E()}})]}),(0,m.jsx)(y.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:A,children:(0,m.jsx)(U,{items:u,tabIndex:A?-1:0,onItemClick:n,activePath:s,level:r+1})})]})}var D=n(2887),H=n(5891);const R="menuExternalLink_NmtK";function G(e){let{item:t,onItemClick:n,activePath:a,level:s,index:r,...c}=e;const{href:d,label:u,className:h,autoAddBaseUrl:b}=t,p=(0,l.w8)(t,a),x=(0,D.A)(d);return(0,m.jsx)("li",{className:(0,i.A)(o.G.docs.docSidebarItemLink,o.G.docs.docSidebarItemLinkLevel(s),"menu__list-item",h),children:(0,m.jsxs)(w.A,{className:(0,i.A)("menu__link",!x&&R,{"menu__link--active":p}),autoAddBaseUrl:b,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,m.jsx)(H.A,{})]})},u)}const P="menuHtmlItem_M9Kj";function W(e){let{item:t,level:n,index:a}=e;const{value:s,defaultStyle:l,className:r}=t;return(0,m.jsx)("li",{className:(0,i.A)(o.G.docs.docSidebarItemLink,o.G.docs.docSidebarItemLinkLevel(n),l&&[P,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:s}},a)}function F(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,m.jsx)(E,{item:t,...n});case"html":return(0,m.jsx)(W,{item:t,...n});default:return(0,m.jsx)(G,{item:t,...n})}}function V(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,m.jsx)(I,{children:a.map(((e,t)=>(0,m.jsx)(F,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(V),Y="menu_SIkG",K="menuWithAnnouncementBar_GW3s";function q(e){let{path:t,sidebar:n,className:s}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,m.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,i.A)("menu thin-scrollbar",Y,l&&K,s),children:(0,m.jsx)("ul",{className:(0,i.A)(o.G.docs.docSidebarMenu,"menu__list"),children:(0,m.jsx)(U,{items:n,activePath:t,level:1})})})}const z="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",J="sidebarHidden_VK0M",Q="sidebarLogo_isFc";function X(e){let{path:t,sidebar:n,onCollapse:a,isHidden:s}=e;const{navbar:{hideOnScroll:o},docs:{sidebar:{hideable:l}}}=(0,f.p)();return(0,m.jsxs)("div",{className:(0,i.A)(z,o&&O,s&&J),children:[o&&(0,m.jsx)(v.A,{tabIndex:-1,className:Q}),(0,m.jsx)(q,{path:t,sidebar:n}),l&&(0,m.jsx)(C,{onClick:a})]})}const Z=a.memo(X);var $=n(3065),ee=n(4635);const te=e=>{let{sidebar:t,path:n}=e;const a=(0,ee.M)();return(0,m.jsx)("ul",{className:(0,i.A)(o.G.docs.docSidebarMenu,"menu__list"),children:(0,m.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ne(e){return(0,m.jsx)($.GX,{component:te,props:e})}const ae=a.memo(ne);function ie(e){const t=(0,j.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,m.jsxs)(m.Fragment,{children:[n&&(0,m.jsx)(Z,{...e}),a&&(0,m.jsx)(ae,{...e})]})}const se={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,m.jsx)("div",{className:se.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,m.jsx)(_,{className:se.expandButtonIcon})})}const le={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function re(e){let{children:t}=e;const n=(0,r.t)();return(0,m.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function ce(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:s}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),s((e=>!e))}),[s,r]);return(0,m.jsx)("aside",{className:(0,i.A)(o.G.docs.docSidebarContainer,le.docSidebarContainer,n&&le.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(le.docSidebarContainer)&&n&&c(!0)},children:(0,m.jsx)(re,{children:(0,m.jsxs)("div",{className:(0,i.A)(le.sidebarViewport,r&&le.sidebarViewportHidden),children:[(0,m.jsx)(ie,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,m.jsx)(oe,{toggleSidebar:d})]})})})}const de={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,m.jsx)("main",{className:(0,i.A)(de.docMainContainer,(t||!a)&&de.docMainContainerEnhanced),children:(0,m.jsx)("div",{className:(0,i.A)("container padding-top--md padding-bottom--lg",de.docItemWrapper,t&&de.docItemWrapperEnhanced),children:n})})}const he={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function me(e){let{children:t}=e;const n=(0,r.t)(),[i,s]=(0,a.useState)(!1);return(0,m.jsxs)("div",{className:he.docsWrapper,children:[(0,m.jsx)(b,{}),(0,m.jsxs)("div",{className:he.docRoot,children:[n&&(0,m.jsx)(ce,{sidebar:n.items,hiddenSidebarContainer:i,setHiddenSidebarContainer:s}),(0,m.jsx)(ue,{hiddenSidebarContainer:i,children:t})]})]})}var be=n(7138);function pe(e){const t=(0,l.B5)(e);if(!t)return(0,m.jsx)(be.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,m.jsx)(s.e3,{className:(0,i.A)(o.G.page.docsDocPage),children:(0,m.jsx)(r.V,{name:a,items:c,children:(0,m.jsx)(me,{children:n})})})}},7138:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),i=n(539),s=n(9303),o=n(4848);function l(e){let{className:t}=e;return(0,o.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,o.jsx)("div",{className:"row",children:(0,o.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,o.jsxs)(s.A,{as:"h1",className:"hero__title",children:[(0,o.jsx)("a",{href:"/",children:(0,o.jsx)("div",{style:{textAlign:"center"},children:(0,o.jsx)("img",{src:"https://rxdb.info/files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"160"})})}),(0,o.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"404 Page Not Found"})]}),(0,o.jsx)("p",{children:(0,o.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it."})}),(0,o.jsx)("p",{children:"Maybe one of these can help you to find the desired content:"}),(0,o.jsx)("div",{className:"ul-container",children:(0,o.jsxs)("ul",{children:[(0,o.jsx)("li",{children:(0,o.jsx)("a",{href:"https://rxdb.info/quickstart.html",children:"RxDB Documentation"})}),(0,o.jsx)("li",{children:(0,o.jsx)("a",{href:"/chat/",children:"RxDB Discord Channel"})}),(0,o.jsx)("li",{children:(0,o.jsx)("a",{href:"https://twitter.com/intent/user?screen_name=rxdbjs",children:"RxDB on twitter"})}),(0,o.jsx)("li",{children:(0,o.jsx)("a",{href:"/code/",children:"RxDB at Github"})})]})})]})})})}}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[9048],{1841:(e,t,n)=>{n.r(t),n.d(t,{default:()=>pe});var a=n(6540),i=n(4164),o=n(1769),s=n(204),l=n(102),r=n(2306),c=n(539),d=n(5627),u=n(7685);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var m=n(4848);function b(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,i]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(o.current?o.current=!1:a>=s?(l(),i(!1)):a{e.location.hash&&(o.current=!0,i(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,m.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,i.A)("clean-btn",s.G.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var p=n(4924),x=n(6347),j=n(6682),f=n(3115),v=n(8173);function _(e){return(0,m.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,m.jsxs)("g",{fill:"#7a7a7a",children:[(0,m.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,m.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const g="collapseSidebarButton_PEFL",A="collapseSidebarButtonIcon_kv0_";function C(e){let{onClick:t}=e;return(0,m.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,i.A)("button button--secondary button--outline",g),onClick:t,children:(0,m.jsx)(_,{className:A})})}var k=n(3380),S=n(6849);const T=Symbol("EmptyContext"),N=a.createContext(T);function I(e){let{children:t}=e;const[n,i]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:i})),[n]);return(0,m.jsx)(N.Provider,{value:o,children:t})}var y=n(3535),B=n(214),w=n(6289),L=n(9136);function M(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,m.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:o,level:r,index:c,...d}=e;const{items:u,label:h,collapsible:b,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:j}}}=(0,f.p)(),v=function(e){const t=(0,L.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,o),g=(0,B.ys)(x,o),{collapsed:A,setCollapsed:C}=(0,y.u)({initialState:()=>!!b&&(!_&&t.collapsed)}),{expandedItem:k,setExpandedItem:I}=function(){const e=(0,a.useContext)(N);if(e===T)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),E=function(e){void 0===e&&(e=!A),I(e?null:c),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:i}=e;const o=(0,S.ZC)(t);(0,a.useEffect)((()=>{t&&!o&&n&&i(!1)}),[t,o,n,i])}({isActive:_,collapsed:A,updateCollapsed:E}),(0,a.useEffect)((()=>{b&&null!=k&&k!==c&&j&&C(!0)}),[b,k,c,C,j]),(0,m.jsxs)("li",{className:(0,i.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":A},p),children:[(0,m.jsxs)("div",{className:(0,i.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":g}),children:[(0,m.jsx)(w.A,{className:(0,i.A)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!x&&b,"menu__link--active":_}),onClick:b?e=>{n?.(t),x?E(!1):(e.preventDefault(),E())}:()=>{n?.(t)},"aria-current":g?"page":void 0,role:b&&!x?"button":void 0,"aria-expanded":b&&!x?!A:void 0,href:b?v??"#":v,...d,children:h}),x&&b&&(0,m.jsx)(M,{collapsed:A,categoryLabel:h,onClick:e=>{e.preventDefault(),E()}})]}),(0,m.jsx)(y.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:A,children:(0,m.jsx)(U,{items:u,tabIndex:A?-1:0,onItemClick:n,activePath:o,level:r+1})})]})}var D=n(2887),H=n(5891);const R="menuExternalLink_NmtK";function G(e){let{item:t,onItemClick:n,activePath:a,level:o,index:r,...c}=e;const{href:d,label:u,className:h,autoAddBaseUrl:b}=t,p=(0,l.w8)(t,a),x=(0,D.A)(d);return(0,m.jsx)("li",{className:(0,i.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(o),"menu__list-item",h),children:(0,m.jsxs)(w.A,{className:(0,i.A)("menu__link",!x&&R,{"menu__link--active":p}),autoAddBaseUrl:b,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,m.jsx)(H.A,{})]})},u)}const P="menuHtmlItem_M9Kj";function W(e){let{item:t,level:n,index:a}=e;const{value:o,defaultStyle:l,className:r}=t;return(0,m.jsx)("li",{className:(0,i.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:o}},a)}function F(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,m.jsx)(E,{item:t,...n});case"html":return(0,m.jsx)(W,{item:t,...n});default:return(0,m.jsx)(G,{item:t,...n})}}function V(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,m.jsx)(I,{children:a.map(((e,t)=>(0,m.jsx)(F,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(V),Y="menu_SIkG",K="menuWithAnnouncementBar_GW3s";function z(e){let{path:t,sidebar:n,className:o}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,m.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,i.A)("menu thin-scrollbar",Y,l&&K,o),children:(0,m.jsx)("ul",{className:(0,i.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,m.jsx)(U,{items:n,activePath:t,level:1})})})}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",J="sidebarHidden_VK0M",Q="sidebarLogo_isFc";function X(e){let{path:t,sidebar:n,onCollapse:a,isHidden:o}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,f.p)();return(0,m.jsxs)("div",{className:(0,i.A)(q,s&&O,o&&J),children:[s&&(0,m.jsx)(v.A,{tabIndex:-1,className:Q}),(0,m.jsx)(z,{path:t,sidebar:n}),l&&(0,m.jsx)(C,{onClick:a})]})}const Z=a.memo(X);var $=n(3065),ee=n(4635);const te=e=>{let{sidebar:t,path:n}=e;const a=(0,ee.M)();return(0,m.jsx)("ul",{className:(0,i.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,m.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ne(e){return(0,m.jsx)($.GX,{component:te,props:e})}const ae=a.memo(ne);function ie(e){const t=(0,j.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,m.jsxs)(m.Fragment,{children:[n&&(0,m.jsx)(Z,{...e}),a&&(0,m.jsx)(ae,{...e})]})}const oe={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function se(e){let{toggleSidebar:t}=e;return(0,m.jsx)("div",{className:oe.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,m.jsx)(_,{className:oe.expandButtonIcon})})}const le={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function re(e){let{children:t}=e;const n=(0,r.t)();return(0,m.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function ce(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),o((e=>!e))}),[o,r]);return(0,m.jsx)("aside",{className:(0,i.A)(s.G.docs.docSidebarContainer,le.docSidebarContainer,n&&le.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(le.docSidebarContainer)&&n&&c(!0)},children:(0,m.jsx)(re,{children:(0,m.jsxs)("div",{className:(0,i.A)(le.sidebarViewport,r&&le.sidebarViewportHidden),children:[(0,m.jsx)(ie,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,m.jsx)(se,{toggleSidebar:d})]})})})}const de={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,m.jsx)("main",{className:(0,i.A)(de.docMainContainer,(t||!a)&&de.docMainContainerEnhanced),children:(0,m.jsx)("div",{className:(0,i.A)("container padding-top--md padding-bottom--lg",de.docItemWrapper,t&&de.docItemWrapperEnhanced),children:n})})}const he={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function me(e){let{children:t}=e;const n=(0,r.t)(),[i,o]=(0,a.useState)(!1);return(0,m.jsxs)("div",{className:he.docsWrapper,children:[(0,m.jsx)(b,{}),(0,m.jsxs)("div",{className:he.docRoot,children:[n&&(0,m.jsx)(ce,{sidebar:n.items,hiddenSidebarContainer:i,setHiddenSidebarContainer:o}),(0,m.jsx)(ue,{hiddenSidebarContainer:i,children:t})]})]})}var be=n(7138);function pe(e){const t=(0,l.B5)(e);if(!t)return(0,m.jsx)(be.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,m.jsx)(o.e3,{className:(0,i.A)(s.G.page.docsDocPage),children:(0,m.jsx)(r.V,{name:a,items:c,children:(0,m.jsx)(me,{children:n})})})}},7138:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),i=n(539),o=n(9303),s=n(4848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsxs)(o.A,{as:"h1",className:"hero__title",children:[(0,s.jsx)("a",{href:"/",children:(0,s.jsx)("div",{style:{textAlign:"center"},children:(0,s.jsx)("img",{src:"https://rxdb.info/files/logo/rxdb_javascript_database.svg",alt:"RxDB",width:"160"})})}),(0,s.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"404 Page Not Found"})]}),(0,s.jsx)("p",{children:(0,s.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"The page you are looking for does not exist anymore or never has existed. If you have found this page through a link, you should tell the link author to update it."})}),(0,s.jsx)("p",{children:"Maybe one of these can help you to find the desired content:"}),(0,s.jsx)("div",{className:"ul-container",children:(0,s.jsxs)("ul",{children:[(0,s.jsx)("li",{children:(0,s.jsx)("a",{href:"https://rxdb.info/overview.html",children:"RxDB Documentation"})}),(0,s.jsx)("li",{children:(0,s.jsx)("a",{href:"/chat/",children:"RxDB Discord Channel"})}),(0,s.jsx)("li",{children:(0,s.jsx)("a",{href:"https://twitter.com/intent/user?screen_name=rxdbjs",children:"RxDB on twitter"})}),(0,s.jsx)("li",{children:(0,s.jsx)("a",{href:"/code/",children:"RxDB at Github"})})]})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/ad16b3ea.abfd4500.js b/docs/assets/js/ad16b3ea.abfd4500.js new file mode 100644 index 00000000000..8113e10bb4e --- /dev/null +++ b/docs/assets/js/ad16b3ea.abfd4500.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[8674],{7580:(e,n,i)=>{i.d(n,{g:()=>d});var t=i(4848);function d(e){const n=[];let i=null;return e.children.forEach((e=>{e.props.id?(i&&n.push(i),i={headline:e,paragraphs:[]}):i&&i.paragraphs.push(e)})),i&&n.push(i),(0,t.jsx)("div",{style:s.stepsContainer,children:n.map(((e,n)=>(0,t.jsxs)("div",{style:s.stepWrapper,children:[(0,t.jsxs)("div",{style:s.stepIndicator,children:[(0,t.jsxs)("div",{style:s.stepNumber,children:[n+1,"."]}),(0,t.jsx)("div",{style:s.verticalLine})]}),(0,t.jsxs)("div",{style:s.stepContent,children:[(0,t.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,n)=>(0,t.jsx)("div",{style:s.item,children:e},n)))]})]},n)))})}const s={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8312:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"dev-mode","title":"Development Mode","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production.","source":"@site/docs/dev-mode.md","sourceDirName":".","slug":"/dev-mode.html","permalink":"/dev-mode.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Development Mode","slug":"dev-mode.html","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production."},"sidebar":"tutorialSidebar","previous":{"title":"Installation","permalink":"/install.html"},"next":{"title":"TypeScript Setup","permalink":"/tutorials/typescript.html"}}');var d=i(4848),s=i(8453),a=i(7580);const r={title:"Development Mode",slug:"dev-mode.html",description:"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production."},l="Dev Mode",o={},c=[{value:"Import the dev-mode Plugin",id:"import-the-dev-mode-plugin",level:3},{value:"Add the Plugin to RxDB",id:"add-the-plugin-to-rxdb",level:2},{value:"Usage with Node.js",id:"usage-with-nodejs",level:2},{value:"Usage with Angular",id:"usage-with-angular",level:2},{value:"Usage with webpack",id:"usage-with-webpack",level:2},{value:"Disable the dev-mode warning",id:"disable-the-dev-mode-warning",level:2},{value:"Disable the tracking iframe",id:"disable-the-tracking-iframe",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"dev-mode",children:"Dev Mode"})}),"\n",(0,d.jsx)(n.p,{children:"The dev-mode plugin adds many checks and validations to RxDB.\nThis ensures that you use the RxDB API properly and so the dev-mode plugin should always be used when\nusing RxDB in development mode."}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:"Adds readable error messages."}),"\n",(0,d.jsxs)(n.li,{children:["Ensures that ",(0,d.jsx)(n.code,{children:"readonly"})," JavaScript objects are not accidentally mutated."]}),"\n",(0,d.jsxs)(n.li,{children:["Adds validation check for validity of schemas, queries, ",(0,d.jsx)(n.a,{href:"/orm.html",children:"ORM"})," methods and document fields.","\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["Notice that the ",(0,d.jsx)(n.code,{children:"dev-mode"})," plugin does not perform schema checks against the data see ",(0,d.jsx)(n.a,{href:"/schema-validation.html",children:"schema validation"})," for that."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,d.jsx)(n.admonition,{type:"warning",children:(0,d.jsxs)(n.p,{children:["The dev-mode plugin will increase your build size and decrease the performance. It must ",(0,d.jsx)(n.strong,{children:"always"})," be used in development. You should ",(0,d.jsx)(n.strong,{children:"never"})," use it in production."]})}),"\n",(0,d.jsxs)(a.g,{children:[(0,d.jsx)(n.h3,{id:"import-the-dev-mode-plugin",children:"Import the dev-mode Plugin"}),(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-javascript",children:"import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';\nimport { addRxPlugin } from 'rxdb/plugins/core';\n"})}),(0,d.jsx)(n.h2,{id:"add-the-plugin-to-rxdb",children:"Add the Plugin to RxDB"}),(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-javascript",children:"addRxPlugin(RxDBDevModePlugin);\n"})})]}),"\n",(0,d.jsx)(n.h2,{id:"usage-with-nodejs",children:"Usage with Node.js"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"async function createDb() {\n if (process.env.NODE_ENV !== \"production\") {\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n const db = createRxDatabase( /* ... */ );\n}\n"})}),"\n",(0,d.jsx)(n.h2,{id:"usage-with-angular",children:"Usage with Angular"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"import { isDevMode } from '@angular/core';\n\nasync function createDb() {\n if (isDevMode()){\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n\n const db = createRxDatabase( /* ... */ );\n // ...\n}\n"})}),"\n",(0,d.jsx)(n.h2,{id:"usage-with-webpack",children:"Usage with webpack"}),"\n",(0,d.jsxs)(n.p,{children:["In the ",(0,d.jsx)(n.code,{children:"webpack.config.js"}),":"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"module.exports = {\n entry: './src/index.ts',\n /* ... */\n plugins: [\n // set a global variable that can be accessed during runtime\n new webpack.DefinePlugin({ MODE: JSON.stringify(\"production\") })\n ]\n /* ... */\n};\n"})}),"\n",(0,d.jsx)(n.p,{children:"In your source code:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"declare var MODE: 'production' | 'development';\n\nasync function createDb() {\n if (MODE === 'development') {\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n const db = createRxDatabase( /* ... */ );\n // ...\n}\n"})}),"\n",(0,d.jsx)(n.h2,{id:"disable-the-dev-mode-warning",children:"Disable the dev-mode warning"}),"\n",(0,d.jsxs)(n.p,{children:["When the dev-mode is enabled, it will print a ",(0,d.jsx)(n.code,{children:"console.warn()"})," message to the console so that you do not accidentally use the dev-mode in production. To disable this warning you can call the ",(0,d.jsx)(n.code,{children:"disableWarnings()"})," function."]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"import { disableWarnings } from 'rxdb/plugins/dev-mode';\ndisableWarnings();\n"})}),"\n",(0,d.jsx)(n.h2,{id:"disable-the-tracking-iframe",children:"Disable the tracking iframe"}),"\n",(0,d.jsxs)(n.p,{children:["When used in localhost and in the browser, the dev-mode plugin can add a tracking iframe to the DOM. This is used to track the effectiveness of marketing efforts of RxDB.\nIf you have ",(0,d.jsx)(n.a,{href:"/premium/",children:"premium access"})," and want to disable this iframe, you can call ",(0,d.jsx)(n.code,{children:"setPremiumFlag()"})," before creating the database."]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-js",children:"import { setPremiumFlag } from 'rxdb-premium/plugins/shared';\nsetPremiumFlag();\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var t=i(6540);const d={},s=t.createContext(d);function a(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:a(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/ad16b3ea.cc970891.js b/docs/assets/js/ad16b3ea.cc970891.js deleted file mode 100644 index 11b0240140a..00000000000 --- a/docs/assets/js/ad16b3ea.cc970891.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[8674],{8312:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>l});const d=JSON.parse('{"id":"dev-mode","title":"Development Mode","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production.","source":"@site/docs/dev-mode.md","sourceDirName":".","slug":"/dev-mode.html","permalink":"/dev-mode.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Development Mode","slug":"dev-mode.html","description":"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production."},"sidebar":"tutorialSidebar","previous":{"title":"Installation","permalink":"/install.html"},"next":{"title":"TypeScript Setup","permalink":"/tutorials/typescript.html"}}');var a=i(4848),s=i(8453);const t={title:"Development Mode",slug:"dev-mode.html",description:"Enable checks & validations with RxDB Dev Mode. Ensure proper API use, readable errors, and schema validation during development. Avoid in production."},r="Dev Mode",o={},l=[{value:"Usage with Node.js",id:"usage-with-nodejs",level:2},{value:"Usage with Angular",id:"usage-with-angular",level:2},{value:"Usage with webpack",id:"usage-with-webpack",level:2},{value:"Disable the dev-mode warning",id:"disable-the-dev-mode-warning",level:2},{value:"Disable the tracking iframe",id:"disable-the-tracking-iframe",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"dev-mode",children:"Dev Mode"})}),"\n",(0,a.jsx)(n.p,{children:"The dev-mode plugin adds many checks and validations to RxDB.\nThis ensures that you use the RxDB API properly and so the dev-mode plugin should always be used when\nusing RxDB in development mode."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Adds readable error messages."}),"\n",(0,a.jsxs)(n.li,{children:["Ensures that ",(0,a.jsx)(n.code,{children:"readonly"})," JavaScript objects are not accidentally mutated."]}),"\n",(0,a.jsxs)(n.li,{children:["Adds validation check for validity of schemas, queries, ",(0,a.jsx)(n.a,{href:"/orm.html",children:"ORM"})," methods and document fields.","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Notice that the ",(0,a.jsx)(n.code,{children:"dev-mode"})," plugin does not perform schema checks against the data see ",(0,a.jsx)(n.a,{href:"/schema-validation.html",children:"schema validation"})," for that."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"warning",children:(0,a.jsxs)(n.p,{children:["The dev-mode plugin will increase your build size and decrease the performance. It must ",(0,a.jsx)(n.strong,{children:"always"})," be used in development. You should ",(0,a.jsx)(n.strong,{children:"never"})," use it in production."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"import { addRxPlugin } from 'rxdb';\nimport { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';\naddRxPlugin(RxDBDevModePlugin);\n"})}),"\n",(0,a.jsx)(n.h2,{id:"usage-with-nodejs",children:"Usage with Node.js"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"async function createDb() {\n if (process.env.NODE_ENV !== \"production\") {\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n const db = createRxDatabase( /* ... */ );\n}\n"})}),"\n",(0,a.jsx)(n.h2,{id:"usage-with-angular",children:"Usage with Angular"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"import { isDevMode } from '@angular/core';\n\nasync function createDb() {\n if (isDevMode()){\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n\n const db = createRxDatabase( /* ... */ );\n // ...\n}\n"})}),"\n",(0,a.jsx)(n.h2,{id:"usage-with-webpack",children:"Usage with webpack"}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"webpack.config.js"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"module.exports = {\n entry: './src/index.ts',\n /* ... */\n plugins: [\n // set a global variable that can be accessed during runtime\n new webpack.DefinePlugin({ MODE: JSON.stringify(\"production\") })\n ]\n /* ... */\n};\n"})}),"\n",(0,a.jsx)(n.p,{children:"In your source code:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"declare var MODE: 'production' | 'development';\n\nasync function createDb() {\n if (MODE === 'development') {\n await import('rxdb/plugins/dev-mode').then(\n module => addRxPlugin(module.RxDBDevModePlugin)\n );\n }\n const db = createRxDatabase( /* ... */ );\n // ...\n}\n"})}),"\n",(0,a.jsx)(n.h2,{id:"disable-the-dev-mode-warning",children:"Disable the dev-mode warning"}),"\n",(0,a.jsxs)(n.p,{children:["When the dev-mode is enabled, it will print a ",(0,a.jsx)(n.code,{children:"console.warn()"})," message to the console so that you do not accidentally use the dev-mode in production. To disable this warning you can call the ",(0,a.jsx)(n.code,{children:"disableWarnings()"})," function."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ts",children:"import { disableWarnings } from 'rxdb/plugins/dev-mode';\ndisableWarnings();\n"})}),"\n",(0,a.jsx)(n.h2,{id:"disable-the-tracking-iframe",children:"Disable the tracking iframe"}),"\n",(0,a.jsxs)(n.p,{children:["When used in localhost and in the browser, the dev-mode plugin can add a tracking iframe to the DOM. This is used to track the effectiveness of marketing efforts of RxDB.\nIf you have ",(0,a.jsx)(n.a,{href:"/premium/",children:"premium access"})," and want to disable this iframe, you can call ",(0,a.jsx)(n.code,{children:"setPremiumFlag()"})," before creating the database."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-js",children:"import { setPremiumFlag } from 'rxdb-premium/plugins/shared';\nsetPremiumFlag();\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>r});var d=i(6540);const a={},s=d.createContext(a);function t(e){const n=d.useContext(s);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),d.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/cde77f4f.32aaf151.js b/docs/assets/js/cde77f4f.cf3732c3.js similarity index 98% rename from docs/assets/js/cde77f4f.32aaf151.js rename to docs/assets/js/cde77f4f.cf3732c3.js index ff4eb6b64a4..47ddbacf8f9 100644 --- a/docs/assets/js/cde77f4f.32aaf151.js +++ b/docs/assets/js/cde77f4f.cf3732c3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2584,6287],{135:(e,r,a)=>{a.d(r,{Pu:()=>t});const s={browser:.3,native:.4,performance:.35,server:.2,sourcecode:0},i=.05;function t(e){const r=e.getLatest()._data.data;return function(e){console.log("-------------------- calculatePrice:"),console.dir(e);let r=0;e.packages.forEach((e=>{const a=s[e];r+=a})),console.log("aimInPercent: "+r);let a=150+r/100*6e4;2===e.packages.length?a*=.95:e.packages.length>2&&(a*=.9);const t=Math.pow(e.teamSize,-.4);if(console.log("input.teamSize ("+a+") "+e.teamSize+" - pricePerDeveloper: "+t),a*=t*e.teamSize,e.packages.includes("sourcecode")){a*=1.75;const e=1520;a1200?100*Math.floor(a/100):50*Math.floor(a/50),{totalPrice:a}}({teamSize:r.developers,packages:r.packages})}},868:(e,r,a)=>{a.r(r),a.d(r,{default:()=>c});var s=a(9136),i=a(6540),t=a(956),n=a(106),l=a(135),o=a(4848);function c(){const e=(0,s.A)();return(0,i.useEffect)((()=>{e&&(async()=>{const e=await Promise.all([a.e(1448),a.e(3304)]).then(a.bind(a,3304));console.log("aaaaaa-iframe dbmodule:"),console.dir(e);const r=await e.getDatabase(),s=await r.getLocal(t.FORM_VALUE_DOCUMENT_ID);console.log("form value docs:"),console.dir(s);const i=await(0,l.Pu)(s);(0,n.c)("premium_lead",Math.floor(i.totalPrice/3),!0)})()})),(0,o.jsxs)("main",{children:[(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsxs)("div",{className:"redirectBox",style:{textAlign:"center"},children:[(0,o.jsx)("a",{href:"/",target:"_blank",children:(0,o.jsx)("div",{className:"logo",children:(0,o.jsx)("img",{src:"/files/logo/logo_text.svg",alt:"RxDB",width:120})})}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("h1",{children:"RxDB Premium Form Submitted"}),(0,o.jsx)("br",{}),(0,o.jsxs)("p",{style:{padding:50},children:["Thank you for submitting the form. You will directly get a confirmation email.",(0,o.jsx)("br",{}),(0,o.jsx)("b",{children:"Please check your spam folder!"}),".",(0,o.jsx)("br",{}),"In the next 24 hours you will get an email with a preview of the license agreement."]}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{})]})]})}},956:(e,r,a)=>{a.r(r),a.d(r,{FORM_VALUE_DOCUMENT_ID:()=>g,TEAM_SIZES:()=>j,default:()=>k});var s=a(797),i=a(6442),t=a(7143),n=a(6540),l=a(7593),o=a(4978),c=a(792),d=a(135),h=a(9136),m=a(7708),p=a(5520),x=a(106),u=a(4848);const g="premium-price-form",j=[1,3,6,12,24,30];let b;function f(){return b||(b=(async()=>{console.log("### FIND formValueDocPromise :;!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");const e=await Promise.all([a.e(1448),a.e(3304)]).then(a.bind(a,3304));console.log("aaaaaa dbmodule:"),console.dir(e);const r=await e.getDatabase();let s=await r.getLocal(g);return s||(s=await r.upsertLocal(g,{formSubmitted:!1,developers:j[1],packages:["browser"]})),console.log("form value doc:"),console.dir(s),s})()),b}function v(e){return(0,u.jsx)("input",{name:"package-"+e.packageName,type:"checkbox",className:"package-checkbox",checked:!!e.formValue?.packages.includes(e.packageName),readOnly:!0,onClick:()=>{(0,x.c)("calculate_premium_price",3,!0),e.onToggle()}})}function k(){const{siteConfig:e}=(0,s.A)(),r=(0,h.A)(),[a,c]=n.useState(!1),[g,j]=n.useState(null);(0,n.useEffect)((()=>{r&&(a||(c(!0),r&&(0,x.c)("open_pricing_page",1,!1),(async()=>{(await f()).$.pipe((0,m.T)((e=>e._data.data)),(0,p.F)(l.b)).subscribe((e=>{console.log("XXX new data:"),console.dir(e),j(e),async function(){const e=await f(),r=(0,d.Pu)(e);console.log("priceResult:"),console.log(JSON.stringify(r,null,4));const a=(0,o.ZN)(document.getElementById("price-calculator-result")),s=(0,o.ZN)(document.getElementById("total-per-project-per-month")),i=(0,o.ZN)(document.getElementById("total-per-project-per-year"));t=r.totalPrice,console.log("setPrice:"),console.dir(t),s.innerHTML=Math.ceil(t/12).toString(),i.innerHTML=Math.ceil(t).toString(),a.style.display="block";var t}()}))})()))}));const[b,k]=n.useState(!1);function w(e){return f().then((r=>r.incrementalModify((r=>(r.packages.includes(e)?r.packages=r.packages.filter((r=>r!==e)):r.packages.push(e),r)))))}return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(t.A,{children:[(0,u.jsx)("body",{className:"homepage"}),(0,u.jsx)("link",{rel:"canonical",href:"/premium/"})]}),(0,u.jsx)(i.A,{title:`Premium Plugins - ${e.title}`,description:"RxDB plugins for professionals. FAQ, pricing and license",children:(0,u.jsxs)("main",{children:[(0,u.jsx)("div",{className:"block first",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB ",(0,u.jsx)("b",{className:"underline",children:"Premium"})]}),(0,u.jsxs)("p",{style:{width:"80%"},children:["RxDB's Premium plugins offer advanced features and performance improvements designed for businesses and professionals. They are ideal for commercial or critical projects, providing ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"better performance"}),", a smaller build size, flexible storage engines, secure encryption and other features."]})]})}),(0,u.jsx)("div",{className:"block dark",id:"price-calculator-block",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsx)("h2",{children:"Price Calculator"}),(0,u.jsx)("div",{className:"price-calculator",children:(0,u.jsx)("div",{className:"price-calculator-inner",children:(0,u.jsx)("form",{id:"price-calculator-form",children:(0,u.jsxs)("div",{className:"packages",children:[(0,u.jsx)("h3",{children:"Packages:"}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"browser",onToggle:()=>w("browser"),formValue:g}),(0,u.jsx)("h4",{children:"Browser Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:"RxStorage OPFS"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:"RxStorage IndexedDB"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:"RxStorage Worker"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:"WebCrypto Encryption"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"native",onToggle:()=>w("native"),formValue:g}),(0,u.jsx)("h4",{children:"Native Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:"RxStorage SQLite"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:"RxStorage Filesystem Node"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"performance",onToggle:()=>w("performance"),formValue:g}),(0,u.jsx)("h4",{children:"Performance Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"RxStorage Sharding"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:"RxStorage Memory Mapped"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:"RxStorage Localstorage Meta Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:"RxStorage Shared Worker"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"server",onToggle:()=>w("server"),formValue:g}),(0,u.jsx)("h4",{children:"Server Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Fastify"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Koa"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)("input",{name:"package-utilities",type:"checkbox",className:"package-checkbox",defaultChecked:!0,disabled:!0}),(0,u.jsxs)("h4",{children:["Utilities Package ",(0,u.jsx)("b",{children:"(always included)"})]}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:"Logger"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:"Fulltext Search"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Vue"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Preact Signals"})})]})]})}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"clear"})]})})})}),(0,u.jsx)("div",{className:"price-calculator",id:"price-calculator-result",style:{marginBottom:90,display:"none"},children:(0,u.jsxs)("div",{className:"price-calculator-inner",children:[(0,u.jsx)("h4",{children:"Calculated Price:"}),(0,u.jsx)("br",{}),(0,u.jsxs)("div",{className:"inner",children:[(0,u.jsx)("span",{className:"price-label",children:"\u20ac"}),(0,u.jsx)("span",{id:"total-per-project-per-month",children:"XX"}),(0,u.jsx)("span",{className:"per-month",children:"/month"}),(0,u.jsx)("span",{className:"clear"})]}),(0,u.jsxs)("div",{className:"inner",children:["(billed yearly: ",(0,u.jsx)("span",{id:"total-per-project-per-year"})," \u20ac)"]}),(0,u.jsx)("br",{}),(0,u.jsx)("br",{}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"button",onClick:()=>{(0,x.c)("open_premium_submit_popup",20,!0),k(!0)},children:"Buy Now \xbb"}),(0,u.jsx)("div",{style:{fontSize:"70%",textAlign:"center"},children:"If you have any questions, see the FAQ below or fill out the Buy-Now Form to get in contact"}),(0,u.jsx)("div",{className:"clear"})]})})]})}),(0,u.jsx)("div",{className:"block",id:"faq",children:(0,u.jsxs)("div",{className:"content centered premium-faq",children:[(0,u.jsxs)("h2",{children:["F.A.Q. ",(0,u.jsx)("b",{children:"(click to toggle)"})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"What is the process for making a purchase?"}),(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:["Fill out the ",(0,u.jsx)("b",{children:"Buy now"})," form below."]}),(0,u.jsx)("li",{children:"You will get a license agreement that you can sign online."}),(0,u.jsx)("li",{children:"You will get an invoice via stripe.com."}),(0,u.jsxs)("li",{children:["After payment you get the access token that you can use to add the Premium plugins to your project with ",(0,u.jsx)("a",{href:"https://www.npmjs.com/package/rxdb-premium",target:"_blank",children:"these instructions"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a discount?"}),"There are multiple ways to get a discount:",(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Contritube to the RxDB github repository"}),(0,u.jsx)("p",{children:"If you have made significant contributions to the RxDB github repository, you can apply for a discount depending on your contribution."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Get 25% off by writing about how you use RxDB"}),(0,u.jsx)("p",{children:"On your company/project website, publish an article/blogpost about how you use RxDB in your project. Include how your setup looks like, how you use RxDB in that setup and what problems you had and how did you overcome them. You also need to link to the RxDB website or documentation pages."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Be active in the RxDB community"}),(0,u.jsx)("p",{children:"If you are active in the RxDB community and discord channel by helping others out or creating educational content like videos and tutorials, feel free to apply for a discount."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Solve one of the free-premium-tasks"}),(0,u.jsxs)("p",{children:["For private personal projects there is the option to solve one of the"," ",(0,u.jsx)("a",{href:"https://github.com/pubkey/rxdb/blob/master/orga/premium-tasks.md",target:"_blank",children:"Premium Tasks"})," ","to get a free 2 years access to the Premium Plugins."]})]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Do I need the Premium Plugins?"}),"RxDB Core is open source and many use cases can be implemented with the Open Core part of RxDB. There are many"," ",(0,u.jsx)("a",{href:"/rx-storage.html",target:"_blank",children:"RxStorage"})," ","options and all core plugins that are required for replication, schema validation, encryption and so on, are totally free. As soon as your application is more than a side project you can consider using the premium plugins as an easy way to improve your applications performance and reduce the build size.",(0,u.jsx)("br",{}),"The main benefit of the Premium Plugins is ",(0,u.jsx)("b",{children:"performance"}),". The Premium RxStorage implementations have a better performance so reading and writing data is much faster especially on low-end devices. You can find a performance comparison"," ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"here"}),". Also there are additional Premium Plugins that can be used to further optimize the performance of your application like the"," ",(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})," ","or the"," ",(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"Sharding"})," ","plugin."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a free trial period?"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:"We do not currently offer a free trial. Instead, we encourage you to explore RxDB's open-source core to evaluate the technology before purchasing the Premium Plugins."}),(0,u.jsxs)("li",{children:["Access to the Premium Plugins requires a signed licensing agreement, which safeguards both parties but also adds administrative overhead. For this reason, we cannot offer free trials or monthly subscriptions; Premium licenses are provided on an ",(0,u.jsx)("b",{children:"annual basis"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I install/build the premium plugins in my CI?"}),"Yes, you can safely install and use the Premium Plugins in your CI without additional payment."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Which payment methods are accepted?"}),(0,u.jsx)("b",{children:"Stripe.com"})," is used as payment processor so most known payment options like credit card, PayPal, SEPA transfer and others are available. A list of all options can be found"," ",(0,u.jsx)("a",{href:"https://stripe.com/docs/payments/payment-methods/overview",title:"stripe payment options",target:"_blank",children:"here"}),"."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Is there any tracking code inside of the premium plugins?"}),"No, the premium plugins themself do not contain any tracking code. When you build your application with RxDB and deploy it to production, it will not make requests from your users to any RxDB server."]})]})}),(0,u.jsx)("div",{className:"block dark",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB Premium Plugins ",(0,u.jsx)("b",{className:"underline",children:"Overview"})]}),(0,u.jsxs)("div",{className:"premium-blocks",children:[(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage IndexedDB"}),(0,u.jsxs)("p",{children:["A storage for browsers based on ",(0,u.jsx)("b",{children:"IndexedDB"}),". Has the best latency on writes and smallest build size."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage OPFS"}),(0,u.jsxs)("p",{children:["Currently the RxStorage with best data throughput that can be used in the browser. Based on the ",(0,u.jsx)("b",{children:"OPFS File System Access API"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SQLite"}),(0,u.jsxs)("p",{children:["A fast storage based on ",(0,u.jsx)("b",{children:"SQLite"})," for Servers and Hybrid Apps. Can be used with"," ",(0,u.jsx)("b",{children:"Node.js"}),", ",(0,u.jsx)("b",{children:"Electron"}),", ",(0,u.jsx)("b",{children:"React Native"}),", ",(0,u.jsx)("b",{children:"Capacitor"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SharedWorker"}),(0,u.jsxs)("p",{children:["A RxStorage wrapper to run the storage inside of a SharedWorker which improves the performance by taking CPU load away from the main process. Used in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Worker"}),(0,u.jsx)("p",{children:"A RxStorage wrapper to run the storage inside of a Worker which improves the performance by taking CPU load away from the main process."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Sharding"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that improves performance by applying the sharding technique."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Memory Mapped"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that creates a mapped in-memory copy which improves performance for the initial page load time and write & read operations."})]})})}),(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Query Optimizer"}),(0,u.jsx)("p",{children:"A tool to find the best index for a given query. You can use this during build time to find the best index and then use that index during runtime."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Localstorage Meta Optimizer"}),(0,u.jsxs)("p",{children:["A wrapper around any other storage which optimizes the initial page load one by using localstorage for meta key-value document. Only works in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"WebCrypto Encryption"}),(0,u.jsx)("p",{children:"A faster and more secure encryption plugin based on the Web Crypto API."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Filesystem Node"}),(0,u.jsxs)("p",{children:["A fast RxStorage based on the ",(0,u.jsx)("b",{children:"Node.js"})," Filesystem."]})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Logger"}),(0,u.jsx)("p",{children:"A logging plugin useful to debug performance problems and for monitoring with Application Performance Monitoring (APM) tools like Bugsnag, Datadog, Elastic, Sentry and others"})]})})}),(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Fastify Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with fastify instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Koa Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with Koa instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"FlexSearch"}),(0,u.jsx)("p",{children:"A plugin to efficiently run local fulltext search indexing and queries."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Vue"}),(0,u.jsx)("p",{children:"An extension for Vue.js to get vue shallow-ref objects to observe RxDB state instead of rxjs observables."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Preact Signals"}),(0,u.jsx)("p",{children:"An extension for react/preact to get preact signals to observe RxDB state instead of rxjs observables."})]})})})]})]})}),(0,u.jsx)(y,{open:b,onClose:()=>{k(!1)}})]})})]})}function y(e){let{onClose:r,open:a}=e;return(0,u.jsx)(c.A,{className:"modal-consulting-page",open:a,width:"auto",onCancel:()=>{r()},closeIcon:null,footer:null,children:(0,u.jsxs)("iframe",{style:{width:"100%",height:"70vh",borderRadius:"32px"},id:"request-project-form",src:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",children:["Your browser doesn't support iframes,"," ",(0,u.jsx)("a",{href:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",target:"_blank",rel:"nofollow",children:"Click here"})]})})}},4978:(e,r,a)=>{function s(e,r){if(!e)throw r||(r=""),new Error("ensureNotFalsy() is falsy: "+r);return e}a.d(r,{ZN:()=>s,bz:()=>i});var i={bufferSize:1,refCount:!0}},7593:(e,r,a)=>{function s(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var a,i;if(Array.isArray(e)){if((a=e.length)!==r.length)return!1;for(i=a;0!=i--;)if(!s(e[i],r[i]))return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===r.toString();var t=Object.keys(e);if((a=t.length)!==Object.keys(r).length)return!1;for(i=a;0!=i--;)if(!Object.prototype.hasOwnProperty.call(r,t[i]))return!1;for(i=a;0!=i--;){var n=t[i];if(!s(e[n],r[n]))return!1}return!0}return e!=e&&r!=r}a.d(r,{b:()=>s})}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2584,6287],{135:(e,r,a)=>{a.d(r,{Pu:()=>t});const s={browser:.3,native:.4,performance:.35,server:.2,sourcecode:0},i=.05;function t(e){const r=e.getLatest()._data.data;return function(e){console.log("-------------------- calculatePrice:"),console.dir(e);let r=0;e.packages.forEach((e=>{const a=s[e];r+=a})),console.log("aimInPercent: "+r);let a=150+r/100*6e4;2===e.packages.length?a*=.95:e.packages.length>2&&(a*=.9);const t=Math.pow(e.teamSize,-.4);if(console.log("input.teamSize ("+a+") "+e.teamSize+" - pricePerDeveloper: "+t),a*=t*e.teamSize,e.packages.includes("sourcecode")){a*=1.75;const e=1520;a1200?100*Math.floor(a/100):50*Math.floor(a/50),{totalPrice:a}}({teamSize:r.developers,packages:r.packages})}},868:(e,r,a)=>{a.r(r),a.d(r,{default:()=>c});var s=a(9136),i=a(6540),t=a(956),n=a(106),l=a(135),o=a(4848);function c(){const e=(0,s.A)();return(0,i.useEffect)((()=>{e&&(async()=>{const e=await Promise.all([a.e(7175),a.e(8164)]).then(a.bind(a,8164));console.log("aaaaaa-iframe dbmodule:"),console.dir(e);const r=await e.getDatabase(),s=await r.getLocal(t.FORM_VALUE_DOCUMENT_ID);console.log("form value docs:"),console.dir(s);const i=await(0,l.Pu)(s);(0,n.c)("premium_lead",Math.floor(i.totalPrice/3),!0)})()})),(0,o.jsxs)("main",{children:[(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsxs)("div",{className:"redirectBox",style:{textAlign:"center"},children:[(0,o.jsx)("a",{href:"/",target:"_blank",children:(0,o.jsx)("div",{className:"logo",children:(0,o.jsx)("img",{src:"/files/logo/logo_text.svg",alt:"RxDB",width:120})})}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{}),(0,o.jsx)("h1",{children:"RxDB Premium Form Submitted"}),(0,o.jsx)("br",{}),(0,o.jsxs)("p",{style:{padding:50},children:["Thank you for submitting the form. You will directly get a confirmation email.",(0,o.jsx)("br",{}),(0,o.jsx)("b",{children:"Please check your spam folder!"}),".",(0,o.jsx)("br",{}),"In the next 24 hours you will get an email with a preview of the license agreement."]}),(0,o.jsx)("br",{}),(0,o.jsx)("br",{})]})]})}},956:(e,r,a)=>{a.r(r),a.d(r,{FORM_VALUE_DOCUMENT_ID:()=>g,TEAM_SIZES:()=>j,default:()=>k});var s=a(797),i=a(6442),t=a(7143),n=a(6540),l=a(7593),o=a(4978),c=a(792),d=a(135),h=a(9136),m=a(7708),p=a(5520),x=a(106),u=a(4848);const g="premium-price-form",j=[1,3,6,12,24,30];let b;function f(){return b||(b=(async()=>{console.log("### FIND formValueDocPromise :;!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");const e=await Promise.all([a.e(7175),a.e(8164)]).then(a.bind(a,8164));console.log("aaaaaa dbmodule:"),console.dir(e);const r=await e.getDatabase();let s=await r.getLocal(g);return s||(s=await r.upsertLocal(g,{formSubmitted:!1,developers:j[1],packages:["browser"]})),console.log("form value doc:"),console.dir(s),s})()),b}function v(e){return(0,u.jsx)("input",{name:"package-"+e.packageName,type:"checkbox",className:"package-checkbox",checked:!!e.formValue?.packages.includes(e.packageName),readOnly:!0,onClick:()=>{(0,x.c)("calculate_premium_price",3,!0),e.onToggle()}})}function k(){const{siteConfig:e}=(0,s.A)(),r=(0,h.A)(),[a,c]=n.useState(!1),[g,j]=n.useState(null);(0,n.useEffect)((()=>{r&&(a||(c(!0),r&&(0,x.c)("open_pricing_page",1,!1),(async()=>{(await f()).$.pipe((0,m.T)((e=>e._data.data)),(0,p.F)(l.b)).subscribe((e=>{console.log("XXX new data:"),console.dir(e),j(e),async function(){const e=await f(),r=(0,d.Pu)(e);console.log("priceResult:"),console.log(JSON.stringify(r,null,4));const a=(0,o.ZN)(document.getElementById("price-calculator-result")),s=(0,o.ZN)(document.getElementById("total-per-project-per-month")),i=(0,o.ZN)(document.getElementById("total-per-project-per-year"));t=r.totalPrice,console.log("setPrice:"),console.dir(t),s.innerHTML=Math.ceil(t/12).toString(),i.innerHTML=Math.ceil(t).toString(),a.style.display="block";var t}()}))})()))}));const[b,k]=n.useState(!1);function w(e){return f().then((r=>r.incrementalModify((r=>(r.packages.includes(e)?r.packages=r.packages.filter((r=>r!==e)):r.packages.push(e),r)))))}return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(t.A,{children:[(0,u.jsx)("body",{className:"homepage"}),(0,u.jsx)("link",{rel:"canonical",href:"/premium/"})]}),(0,u.jsx)(i.A,{title:`Premium Plugins - ${e.title}`,description:"RxDB plugins for professionals. FAQ, pricing and license",children:(0,u.jsxs)("main",{children:[(0,u.jsx)("div",{className:"block first",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB ",(0,u.jsx)("b",{className:"underline",children:"Premium"})]}),(0,u.jsxs)("p",{style:{width:"80%"},children:["RxDB's Premium plugins offer advanced features and performance improvements designed for businesses and professionals. They are ideal for commercial or critical projects, providing ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"better performance"}),", a smaller build size, flexible storage engines, secure encryption and other features."]})]})}),(0,u.jsx)("div",{className:"block dark",id:"price-calculator-block",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsx)("h2",{children:"Price Calculator"}),(0,u.jsx)("div",{className:"price-calculator",children:(0,u.jsx)("div",{className:"price-calculator-inner",children:(0,u.jsx)("form",{id:"price-calculator-form",children:(0,u.jsxs)("div",{className:"packages",children:[(0,u.jsx)("h3",{children:"Packages:"}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"browser",onToggle:()=>w("browser"),formValue:g}),(0,u.jsx)("h4",{children:"Browser Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:"RxStorage OPFS"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:"RxStorage IndexedDB"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:"RxStorage Worker"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:"WebCrypto Encryption"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"native",onToggle:()=>w("native"),formValue:g}),(0,u.jsx)("h4",{children:"Native Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:"RxStorage SQLite"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:"RxStorage Filesystem Node"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"performance",onToggle:()=>w("performance"),formValue:g}),(0,u.jsx)("h4",{children:"Performance Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"RxStorage Sharding"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:"RxStorage Memory Mapped"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:"RxStorage Localstorage Meta Optimizer"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:"RxStorage Shared Worker"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)(v,{packageName:"server",onToggle:()=>w("server"),formValue:g}),(0,u.jsx)("h4",{children:"Server Package"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Fastify"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:"RxServer Adapter Koa"})})]})]})}),(0,u.jsx)("div",{className:"package bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"package-inner",children:[(0,u.jsx)("input",{name:"package-utilities",type:"checkbox",className:"package-checkbox",defaultChecked:!0,disabled:!0}),(0,u.jsxs)("h4",{children:["Utilities Package ",(0,u.jsx)("b",{children:"(always included)"})]}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:"Logger"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:"Fulltext Search"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Vue"})}),(0,u.jsx)("li",{children:(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:"Reactivity Preact Signals"})})]})]})}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"clear"})]})})})}),(0,u.jsx)("div",{className:"price-calculator",id:"price-calculator-result",style:{marginBottom:90,display:"none"},children:(0,u.jsxs)("div",{className:"price-calculator-inner",children:[(0,u.jsx)("h4",{children:"Calculated Price:"}),(0,u.jsx)("br",{}),(0,u.jsxs)("div",{className:"inner",children:[(0,u.jsx)("span",{className:"price-label",children:"\u20ac"}),(0,u.jsx)("span",{id:"total-per-project-per-month",children:"XX"}),(0,u.jsx)("span",{className:"per-month",children:"/month"}),(0,u.jsx)("span",{className:"clear"})]}),(0,u.jsxs)("div",{className:"inner",children:["(billed yearly: ",(0,u.jsx)("span",{id:"total-per-project-per-year"})," \u20ac)"]}),(0,u.jsx)("br",{}),(0,u.jsx)("br",{}),(0,u.jsx)("div",{className:"clear"}),(0,u.jsx)("div",{className:"button",onClick:()=>{(0,x.c)("open_premium_submit_popup",20,!0),k(!0)},children:"Buy Now \xbb"}),(0,u.jsx)("div",{style:{fontSize:"70%",textAlign:"center"},children:"If you have any questions, see the FAQ below or fill out the Buy-Now Form to get in contact"}),(0,u.jsx)("div",{className:"clear"})]})})]})}),(0,u.jsx)("div",{className:"block",id:"faq",children:(0,u.jsxs)("div",{className:"content centered premium-faq",children:[(0,u.jsxs)("h2",{children:["F.A.Q. ",(0,u.jsx)("b",{children:"(click to toggle)"})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"What is the process for making a purchase?"}),(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:["Fill out the ",(0,u.jsx)("b",{children:"Buy now"})," form below."]}),(0,u.jsx)("li",{children:"You will get a license agreement that you can sign online."}),(0,u.jsx)("li",{children:"You will get an invoice via stripe.com."}),(0,u.jsxs)("li",{children:["After payment you get the access token that you can use to add the Premium plugins to your project with ",(0,u.jsx)("a",{href:"https://www.npmjs.com/package/rxdb-premium",target:"_blank",children:"these instructions"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a discount?"}),"There are multiple ways to get a discount:",(0,u.jsxs)("ul",{children:[(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Contritube to the RxDB github repository"}),(0,u.jsx)("p",{children:"If you have made significant contributions to the RxDB github repository, you can apply for a discount depending on your contribution."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Get 25% off by writing about how you use RxDB"}),(0,u.jsx)("p",{children:"On your company/project website, publish an article/blogpost about how you use RxDB in your project. Include how your setup looks like, how you use RxDB in that setup and what problems you had and how did you overcome them. You also need to link to the RxDB website or documentation pages."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Be active in the RxDB community"}),(0,u.jsx)("p",{children:"If you are active in the RxDB community and discord channel by helping others out or creating educational content like videos and tutorials, feel free to apply for a discount."})]}),(0,u.jsxs)("li",{children:[(0,u.jsx)("h5",{children:"Solve one of the free-premium-tasks"}),(0,u.jsxs)("p",{children:["For private personal projects there is the option to solve one of the"," ",(0,u.jsx)("a",{href:"https://github.com/pubkey/rxdb/blob/master/orga/premium-tasks.md",target:"_blank",children:"Premium Tasks"})," ","to get a free 2 years access to the Premium Plugins."]})]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Do I need the Premium Plugins?"}),"RxDB Core is open source and many use cases can be implemented with the Open Core part of RxDB. There are many"," ",(0,u.jsx)("a",{href:"/rx-storage.html",target:"_blank",children:"RxStorage"})," ","options and all core plugins that are required for replication, schema validation, encryption and so on, are totally free. As soon as your application is more than a side project you can consider using the premium plugins as an easy way to improve your applications performance and reduce the build size.",(0,u.jsx)("br",{}),"The main benefit of the Premium Plugins is ",(0,u.jsx)("b",{children:"performance"}),". The Premium RxStorage implementations have a better performance so reading and writing data is much faster especially on low-end devices. You can find a performance comparison"," ",(0,u.jsx)("a",{href:"/rx-storage-performance.html",target:"_blank",children:"here"}),". Also there are additional Premium Plugins that can be used to further optimize the performance of your application like the"," ",(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:"Query Optimizer"})," ","or the"," ",(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:"Sharding"})," ","plugin."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I get a free trial period?"}),(0,u.jsxs)("ul",{children:[(0,u.jsx)("li",{children:"We do not currently offer a free trial. Instead, we encourage you to explore RxDB's open-source core to evaluate the technology before purchasing the Premium Plugins."}),(0,u.jsxs)("li",{children:["Access to the Premium Plugins requires a signed licensing agreement, which safeguards both parties but also adds administrative overhead. For this reason, we cannot offer free trials or monthly subscriptions; Premium licenses are provided on an ",(0,u.jsx)("b",{children:"annual basis"}),"."]})]})]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Can I install/build the premium plugins in my CI?"}),"Yes, you can safely install and use the Premium Plugins in your CI without additional payment."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Which payment methods are accepted?"}),(0,u.jsx)("b",{children:"Stripe.com"})," is used as payment processor so most known payment options like credit card, PayPal, SEPA transfer and others are available. A list of all options can be found"," ",(0,u.jsx)("a",{href:"https://stripe.com/docs/payments/payment-methods/overview",title:"stripe payment options",target:"_blank",children:"here"}),"."]}),(0,u.jsxs)("details",{children:[(0,u.jsx)("summary",{children:"Is there any tracking code inside of the premium plugins?"}),"No, the premium plugins themself do not contain any tracking code. When you build your application with RxDB and deploy it to production, it will not make requests from your users to any RxDB server."]})]})}),(0,u.jsx)("div",{className:"block dark",children:(0,u.jsxs)("div",{className:"content centered",children:[(0,u.jsxs)("h2",{children:["RxDB Premium Plugins ",(0,u.jsx)("b",{className:"underline",children:"Overview"})]}),(0,u.jsxs)("div",{className:"premium-blocks",children:[(0,u.jsx)("a",{href:"/rx-storage-indexeddb.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage IndexedDB"}),(0,u.jsxs)("p",{children:["A storage for browsers based on ",(0,u.jsx)("b",{children:"IndexedDB"}),". Has the best latency on writes and smallest build size."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-opfs.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage OPFS"}),(0,u.jsxs)("p",{children:["Currently the RxStorage with best data throughput that can be used in the browser. Based on the ",(0,u.jsx)("b",{children:"OPFS File System Access API"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sqlite.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SQLite"}),(0,u.jsxs)("p",{children:["A fast storage based on ",(0,u.jsx)("b",{children:"SQLite"})," for Servers and Hybrid Apps. Can be used with"," ",(0,u.jsx)("b",{children:"Node.js"}),", ",(0,u.jsx)("b",{children:"Electron"}),", ",(0,u.jsx)("b",{children:"React Native"}),", ",(0,u.jsx)("b",{children:"Capacitor"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-shared-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage SharedWorker"}),(0,u.jsxs)("p",{children:["A RxStorage wrapper to run the storage inside of a SharedWorker which improves the performance by taking CPU load away from the main process. Used in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/rx-storage-worker.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Worker"}),(0,u.jsx)("p",{children:"A RxStorage wrapper to run the storage inside of a Worker which improves the performance by taking CPU load away from the main process."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-sharding.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Sharding"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that improves performance by applying the sharding technique."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-memory-mapped.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Memory Mapped"}),(0,u.jsx)("p",{children:"A wrapper around any other storage that creates a mapped in-memory copy which improves performance for the initial page load time and write & read operations."})]})})}),(0,u.jsx)("a",{href:"/query-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Query Optimizer"}),(0,u.jsx)("p",{children:"A tool to find the best index for a given query. You can use this during build time to find the best index and then use that index during runtime."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-localstorage-meta-optimizer.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Localstorage Meta Optimizer"}),(0,u.jsxs)("p",{children:["A wrapper around any other storage which optimizes the initial page load one by using localstorage for meta key-value document. Only works in ",(0,u.jsx)("b",{children:"browsers"}),"."]})]})})}),(0,u.jsx)("a",{href:"/encryption.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"WebCrypto Encryption"}),(0,u.jsx)("p",{children:"A faster and more secure encryption plugin based on the Web Crypto API."})]})})}),(0,u.jsx)("a",{href:"/rx-storage-filesystem-node.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxStorage Filesystem Node"}),(0,u.jsxs)("p",{children:["A fast RxStorage based on the ",(0,u.jsx)("b",{children:"Node.js"})," Filesystem."]})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Logger"}),(0,u.jsx)("p",{children:"A logging plugin useful to debug performance problems and for monitoring with Application Performance Monitoring (APM) tools like Bugsnag, Datadog, Elastic, Sentry and others"})]})})}),(0,u.jsx)("a",{href:"/rx-server.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Fastify Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with fastify instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/logger.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"RxServer Koa Adapter"}),(0,u.jsx)("p",{children:"An adapter to use the RxServer with Koa instead of express. Used to have better performance when serving requests."})]})})}),(0,u.jsx)("a",{href:"/fulltext-search.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"FlexSearch"}),(0,u.jsx)("p",{children:"A plugin to efficiently run local fulltext search indexing and queries."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-left-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Vue"}),(0,u.jsx)("p",{children:"An extension for Vue.js to get vue shallow-ref objects to observe RxDB state instead of rxjs observables."})]})})}),(0,u.jsx)("a",{href:"/reactivity.html",target:"_blank",children:(0,u.jsx)("div",{className:"premium-block hover-shadow-middle bg-gradient-right-top",children:(0,u.jsxs)("div",{className:"premium-block-inner",children:[(0,u.jsx)("h4",{children:"Reactivity Preact Signals"}),(0,u.jsx)("p",{children:"An extension for react/preact to get preact signals to observe RxDB state instead of rxjs observables."})]})})})]})]})}),(0,u.jsx)(y,{open:b,onClose:()=>{k(!1)}})]})})]})}function y(e){let{onClose:r,open:a}=e;return(0,u.jsx)(c.A,{className:"modal-consulting-page",open:a,width:"auto",onCancel:()=>{r()},closeIcon:null,footer:null,children:(0,u.jsxs)("iframe",{style:{width:"100%",height:"70vh",borderRadius:"32px"},id:"request-project-form",src:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",children:["Your browser doesn't support iframes,"," ",(0,u.jsx)("a",{href:"https://webforms.pipedrive.com/f/ccHQ5wi8dHxdFgcxEnRfXaXv2uTGnLNwP4tPAGO3hgSFan8xa5j7Kr3LH5OXzWQo2T",target:"_blank",rel:"nofollow",children:"Click here"})]})})}},4978:(e,r,a)=>{function s(e,r){if(!e)throw r||(r=""),new Error("ensureNotFalsy() is falsy: "+r);return e}a.d(r,{ZN:()=>s,bz:()=>i});var i={bufferSize:1,refCount:!0}},7593:(e,r,a)=>{function s(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var a,i;if(Array.isArray(e)){if((a=e.length)!==r.length)return!1;for(i=a;0!=i--;)if(!s(e[i],r[i]))return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===r.toString();var t=Object.keys(e);if((a=t.length)!==Object.keys(r).length)return!1;for(i=a;0!=i--;)if(!Object.prototype.hasOwnProperty.call(r,t[i]))return!1;for(i=a;0!=i--;){var n=t[i];if(!s(e[n],r[n]))return!1}return!0}return e!=e&&r!=r}a.d(r,{b:()=>s})}}]); \ No newline at end of file diff --git a/docs/assets/js/d622bd51.eb0d3b82.js b/docs/assets/js/d622bd51.4cd4c223.js similarity index 62% rename from docs/assets/js/d622bd51.eb0d3b82.js rename to docs/assets/js/d622bd51.4cd4c223.js index a613d1e9c73..52133458e77 100644 --- a/docs/assets/js/d622bd51.eb0d3b82.js +++ b/docs/assets/js/d622bd51.4cd4c223.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2845],{1894:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"migration-schema","title":"Seamless Schema Data Migration with RxDB","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly.","source":"@site/docs/migration-schema.md","sourceDirName":".","slug":"/migration-schema.html","permalink":"/migration-schema.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Seamless Schema Data Migration with RxDB","slug":"migration-schema.html","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly."},"sidebar":"tutorialSidebar","previous":{"title":"Errors","permalink":"/errors.html"},"next":{"title":"Storage Migration","permalink":"/migration-storage.html"}}');var o=t(4848),s=t(8453);const i={title:"Seamless Schema Data Migration with RxDB",slug:"migration-schema.html",description:"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly."},r="Migrate Database Data on schema changes",l={},c=[{value:"Providing strategies",id:"providing-strategies",level:2},{value:"autoMigrate",id:"automigrate",level:2},{value:"migrationStates()",id:"migrationstates",level:2},{value:"Migrating attachments",id:"migrating-attachments",level:2},{value:"Migration on multi-tab in browsers",id:"migration-on-multi-tab-in-browsers",level:2},{value:"Migration and Replication",id:"migration-and-replication",level:2},{value:"Migration should be run on all database instances",id:"migration-should-be-run-on-all-database-instances",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"migrate-database-data-on-schema-changes",children:"Migrate Database Data on schema changes"})}),"\n",(0,o.jsxs)(n.p,{children:["The RxDB Data Migration Plugin helps developers easily update stored data in their apps when they make changes to the data structure by changing the schema of a ",(0,o.jsx)(n.a,{href:"/rx-collection.html",children:"RxCollection"}),". This is useful when developers release a new version of the app with a different schema."]}),"\n",(0,o.jsxs)(n.p,{children:["Imagine you have your awesome messenger-app distributed to many users. After a while, you decide that in your new version, you want to change the schema of the messages-collection. Instead of saving the message-date like ",(0,o.jsx)(n.code,{children:"2017-02-12T23:03:05+00:00"})," you want to have the unix-timestamp like ",(0,o.jsx)(n.code,{children:"1486940585"})," to make it easier to compare dates. To accomplish this, you change the schema and ",(0,o.jsx)(n.strong,{children:"increase the version-number"})," and you also change your code where you save the incoming messages. But one problem remains: what happens with the messages which are already stored in the database on the user's device in the old schema?"]}),"\n",(0,o.jsx)(n.p,{children:"With RxDB you can provide migrationStrategies for your collections that automatically (or on call) transform your existing data from older to newer schemas. This assures that the client's data always matches your newest code-version."}),"\n",(0,o.jsx)(n.h1,{id:"add-the-migration-plugin",children:"Add the migration plugin"}),"\n",(0,o.jsxs)(n.p,{children:["To enable the data migration, you have to add the ",(0,o.jsx)(n.code,{children:"migration-schema"})," plugin."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"import { addRxPlugin } from 'rxdb';\nimport { RxDBMigrationSchemaPlugin } from 'rxdb/plugins/migration-schema';\naddRxPlugin(RxDBMigrationSchemaPlugin);\n"})}),"\n",(0,o.jsx)(n.h2,{id:"providing-strategies",children:"Providing strategies"}),"\n",(0,o.jsxs)(n.p,{children:["Upon creation of a collection, you have to provide migrationStrategies when your schema's version-number is greater than ",(0,o.jsx)(n.code,{children:"0"}),". To do this, you have to add an object to the ",(0,o.jsx)(n.code,{children:"migrationStrategies"})," property where a function for every schema-version is assigned. A migrationStrategy is a function which gets the old document-data as a parameter and returns the new, transformed document-data. If the strategy returns ",(0,o.jsx)(n.code,{children:"null"}),", the document will be removed instead of migrated."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n // 1 means, this transforms data from version 0 to version 1\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.p,{children:"Asynchronous strategies can also be used:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n },\n /**\n * 2 means, this transforms data from version 1 to version 2\n * this returns a promise which resolves with the new document-data\n */\n 2: function(oldDoc){\n // in the new schema (version: 2) we defined 'senderCountry' as required field (string)\n // so we must get the country of the message-sender from the server\n const coordinates = oldDoc.coordinates;\n return fetch('http://myserver.com/api/countryByCoordinates/'+coordinates+'/')\n .then(response => {\n const response = response.json();\n oldDoc.senderCountry = response;\n return oldDoc;\n });\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.p,{children:"you can also filter which documents should be migrated:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n // 1 means, this transforms data from version 0 to version 1\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n },\n /**\n * this removes all documents older then 2017-02-12\n * they will not appear in the new collection\n */\n 2: function(oldDoc){\n if(oldDoc.time < 1486940585) return null;\n else return oldDoc;\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.h2,{id:"automigrate",children:"autoMigrate"}),"\n",(0,o.jsxs)(n.p,{children:["By default, the migration automatically happens when the collection is created. Calling ",(0,o.jsx)(n.code,{children:"RxDatabase.addCollections()"})," returns only when the migration has finished.\nIf you have lots of data or the migrationStrategies take a long time, it might be better to start the migration 'by hand' and show the migration-state to the user as a loading-bar."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"const messageCol = await myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n autoMigrate: false, // <- migration will not run at creation\n migrationStrategies: {\n 1: async function(oldDoc){\n ...\n anything that takes very long\n ...\n return oldDoc;\n }\n }\n }\n});\n\n// check if migration is needed\nconst needed = await messageCol.migrationNeeded();\nif(needed == false) return;\n\n// start the migration\nmessageCol.startMigration(10); // 10 is the batch-size, how many docs will run at parallel\n\nconst migrationState = messageCol.getMigrationState();\n\n// 'start' the observable\nmigrationState.$.subscribe(\n state => console.dir(state),\n error => console.error(error),\n done => console.log('done')\n);\n\n// the emitted states look like this:\n{\n status: 'RUNNING' // oneOf 'RUNNING' | 'DONE' | 'ERROR'\n count: {\n total: 50, // amount of documents which must be migrated\n handled: 0, // amount of handled docs\n percent: 0 // percentage [0-100]\n }\n}\n\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you don't want to show the state to the user, you can also use ",(0,o.jsx)(n.code,{children:".migratePromise()"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:" const migrationPromise = messageCol.migratePromise(10);\n await migratePromise;\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migrationstates",children:"migrationStates()"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"RxDatabase.migrationStates()"})," returns an ",(0,o.jsx)(n.code,{children:"Observable"})," that emits all migration states of any collection of the database.\nUse this when you add collections dynamically and want to show a loading-state of the migrations to the user."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"const allStatesObservable = myDatabase.migrationStates();\nallStatesObservable.subscribe(allStates => {\n allStates.forEach(migrationState => {\n console.log(\n 'migration state of ' +\n migrationState.collection.name\n );\n });\n});\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migrating-attachments",children:"Migrating attachments"}),"\n",(0,o.jsxs)(n.p,{children:["When you store ",(0,o.jsx)(n.code,{children:"RxAttachment"}),"s together with your document, they can also be changed, added or removed while running the migration.\nYou can do this by mutating the ",(0,o.jsx)(n.code,{children:"oldDoc._attachments"})," property."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"import { createBlob } from 'rxdb';\nconst migrationStrategies = {\n 1: async function(oldDoc){\n // do nothing with _attachments to keep all attachments and have them in the new collection version.\n return oldDoc;\n },\n 2: async function(oldDoc){\n // set _attachments to an empty object to delete all existing ones during the migration.\n oldDoc._attachments = {};\n return oldDoc;\n }\n 3: async function(oldDoc){\n // update the data field of a single attachment to change its data. \n oldDoc._attachments.myFile.data = await createBlob(\n 'my new text',\n oldDoc._attachments.myFile.content_type\n );\n return oldDoc;\n }\n}\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migration-on-multi-tab-in-browsers",children:"Migration on multi-tab in browsers"}),"\n",(0,o.jsxs)(n.p,{children:["If you use RxDB in a multiInstance environment, like a browser, it will ensure that exactly one tab is running a migration of a collection.\nAlso the ",(0,o.jsx)(n.code,{children:"migrationState.$"})," events are emitted between browser tabs."]}),"\n",(0,o.jsx)(n.h2,{id:"migration-and-replication",children:"Migration and Replication"}),"\n",(0,o.jsxs)(n.p,{children:["If you use any of the ",(0,o.jsx)(n.a,{href:"/replication.html",children:"RxReplication"})," plugins, the migration will also run on the internal replication-state storage. It will migrate all ",(0,o.jsx)(n.code,{children:"assumedMasterState"})," documents\nso that after the migration is done, you do not have to re-run the replication from scratch.\nRxDB assumes that you run the exact same migration on the servers and the clients. Notice that the replication ",(0,o.jsx)(n.code,{children:"pull-checkpoint"})," will not be migrated. Your backend must be compatible with pull-checkpoints of older versions."]}),"\n",(0,o.jsx)(n.h2,{id:"migration-should-be-run-on-all-database-instances",children:"Migration should be run on all database instances"}),"\n",(0,o.jsxs)(n.p,{children:["If you have multiple database instances (for example, if you are running replication inside of a ",(0,o.jsx)(n.a,{href:"/rx-storage-worker.html",children:"Worker"})," or ",(0,o.jsx)(n.a,{href:"/rx-storage-shared-worker.html",children:"SharedWorker"})," and have created a database instance inside of the worker), schema migration should be started on all database instances. All instances must know about all migration strategies and any updated schema versions."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var a=t(6540);const o={},s=a.createContext(o);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[2845],{1894:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"migration-schema","title":"Seamless Schema Data Migration with RxDB","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly.","source":"@site/docs/migration-schema.md","sourceDirName":".","slug":"/migration-schema.html","permalink":"/migration-schema.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Seamless Schema Data Migration with RxDB","slug":"migration-schema.html","description":"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly."},"sidebar":"tutorialSidebar","previous":{"title":"Errors","permalink":"/errors.html"},"next":{"title":"Storage Migration","permalink":"/migration-storage.html"}}');var o=t(4848),s=t(8453);const i={title:"Seamless Schema Data Migration with RxDB",slug:"migration-schema.html",description:"Upgrade your RxDB collections without losing data. Learn how to seamlessly migrate schema changes and keep your apps running smoothly."},r="Migrate Database Data on schema changes",l={},c=[{value:"Providing strategies",id:"providing-strategies",level:2},{value:"autoMigrate",id:"automigrate",level:2},{value:"migrationStates()",id:"migrationstates",level:2},{value:"Migrating attachments",id:"migrating-attachments",level:2},{value:"Migration on multi-tab in browsers",id:"migration-on-multi-tab-in-browsers",level:2},{value:"Migration and Replication",id:"migration-and-replication",level:2},{value:"Migration should be run on all database instances",id:"migration-should-be-run-on-all-database-instances",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"migrate-database-data-on-schema-changes",children:"Migrate Database Data on schema changes"})}),"\n",(0,o.jsxs)(n.p,{children:["The RxDB Data Migration Plugin helps developers easily update stored data in their apps when they make changes to the data structure by changing the schema of a ",(0,o.jsx)(n.a,{href:"/rx-collection.html",children:"RxCollection"}),". This is useful when developers release a new version of the app with a different schema."]}),"\n",(0,o.jsxs)(n.p,{children:["Imagine you have your awesome messenger-app distributed to many users. After a while, you decide that in your new version, you want to change the schema of the messages-collection. Instead of saving the message-date like ",(0,o.jsx)(n.code,{children:"2017-02-12T23:03:05+00:00"})," you want to have the unix-timestamp like ",(0,o.jsx)(n.code,{children:"1486940585"})," to make it easier to compare dates. To accomplish this, you change the schema and ",(0,o.jsx)(n.strong,{children:"increase the version-number"})," and you also change your code where you save the incoming messages. But one problem remains: what happens with the messages which are already stored in the database on the user's device in the old schema?"]}),"\n",(0,o.jsx)(n.p,{children:"With RxDB you can provide migrationStrategies for your collections that automatically (or on call) transform your existing data from older to newer schemas. This assures that the client's data always matches your newest code-version."}),"\n",(0,o.jsx)(n.h1,{id:"add-the-migration-plugin",children:"Add the migration plugin"}),"\n",(0,o.jsxs)(n.p,{children:["To enable the data migration, you have to add the ",(0,o.jsx)(n.code,{children:"migration-schema"})," plugin."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"import { addRxPlugin } from 'rxdb';\nimport { RxDBMigrationSchemaPlugin } from 'rxdb/plugins/migration-schema';\naddRxPlugin(RxDBMigrationSchemaPlugin);\n"})}),"\n",(0,o.jsx)(n.h2,{id:"providing-strategies",children:"Providing strategies"}),"\n",(0,o.jsxs)(n.p,{children:["Upon creation of a collection, you have to provide migrationStrategies when your schema's version-number is greater than ",(0,o.jsx)(n.code,{children:"0"}),". To do this, you have to add an object to the ",(0,o.jsx)(n.code,{children:"migrationStrategies"})," property where a function for every schema-version is assigned. A migrationStrategy is a function which gets the old document-data as a parameter and returns the new, transformed document-data. If the strategy returns ",(0,o.jsx)(n.code,{children:"null"}),", the document will be removed instead of migrated."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n // 1 means, this transforms data from version 0 to version 1\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.p,{children:"Asynchronous strategies can also be used:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n },\n /**\n * 2 means, this transforms data from version 1 to version 2\n * this returns a promise which resolves with the new document-data\n */\n 2: function(oldDoc){\n // in the new schema (version: 2) we defined 'senderCountry' as required field (string)\n // so we must get the country of the message-sender from the server\n const coordinates = oldDoc.coordinates;\n return fetch('http://myserver.com/api/countryByCoordinates/'+coordinates+'/')\n .then(response => {\n const response = response.json();\n oldDoc.senderCountry = response;\n return oldDoc;\n });\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.p,{children:"you can also filter which documents should be migrated:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n migrationStrategies: {\n // 1 means, this transforms data from version 0 to version 1\n 1: function(oldDoc){\n oldDoc.time = new Date(oldDoc.time).getTime(); // string to unix\n return oldDoc;\n },\n /**\n * this removes all documents older then 2017-02-12\n * they will not appear in the new collection\n */\n 2: function(oldDoc){\n if(oldDoc.time < 1486940585) return null;\n else return oldDoc;\n }\n }\n }\n});\n"})}),"\n",(0,o.jsx)(n.h2,{id:"automigrate",children:"autoMigrate"}),"\n",(0,o.jsxs)(n.p,{children:["By default, the migration automatically happens when the collection is created. Calling ",(0,o.jsx)(n.code,{children:"RxDatabase.addCollections()"})," returns only when the migration has finished.\nIf you have lots of data or the migrationStrategies take a long time, it might be better to start the migration 'by hand' and show the migration-state to the user as a loading-bar."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-javascript",children:"const messageCol = await myDatabase.addCollections({\n messages: {\n schema: messageSchemaV1,\n autoMigrate: false, // <- migration will not run at creation\n migrationStrategies: {\n 1: async function(oldDoc){\n ...\n anything that takes very long\n ...\n return oldDoc;\n }\n }\n }\n});\n\n// check if migration is needed\nconst needed = await messageCol.migrationNeeded();\nif(needed == false) return;\n\n// start the migration\nmessageCol.startMigration(10); // 10 is the batch-size, how many docs will run at parallel\n\nconst migrationState = messageCol.getMigrationState();\n\n// 'start' the observable\nmigrationState.$.subscribe({\n next: state => console.dir(state),\n error: error => console.error(error),\n complete: () => console.log('done')\n});\n\n// the emitted states look like this:\n{\n status: 'RUNNING' // oneOf 'RUNNING' | 'DONE' | 'ERROR'\n count: {\n total: 50, // amount of documents which must be migrated\n handled: 0, // amount of handled docs\n percent: 0 // percentage [0-100]\n }\n}\n\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you don't want to show the state to the user, you can also use ",(0,o.jsx)(n.code,{children:".migratePromise()"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:" const migrationPromise = messageCol.migratePromise(10);\n await migratePromise;\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migrationstates",children:"migrationStates()"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"RxDatabase.migrationStates()"})," returns an ",(0,o.jsx)(n.code,{children:"Observable"})," that emits all migration states of any collection of the database.\nUse this when you add collections dynamically and want to show a loading-state of the migrations to the user."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"const allStatesObservable = myDatabase.migrationStates();\nallStatesObservable.subscribe(allStates => {\n allStates.forEach(migrationState => {\n console.log(\n 'migration state of ' +\n migrationState.collection.name\n );\n });\n});\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migrating-attachments",children:"Migrating attachments"}),"\n",(0,o.jsxs)(n.p,{children:["When you store ",(0,o.jsx)(n.code,{children:"RxAttachment"}),"s together with your document, they can also be changed, added or removed while running the migration.\nYou can do this by mutating the ",(0,o.jsx)(n.code,{children:"oldDoc._attachments"})," property."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"import { createBlob } from 'rxdb';\nconst migrationStrategies = {\n 1: async function(oldDoc){\n // do nothing with _attachments to keep all attachments and have them in the new collection version.\n return oldDoc;\n },\n 2: async function(oldDoc){\n // set _attachments to an empty object to delete all existing ones during the migration.\n oldDoc._attachments = {};\n return oldDoc;\n }\n 3: async function(oldDoc){\n // update the data field of a single attachment to change its data. \n oldDoc._attachments.myFile.data = await createBlob(\n 'my new text',\n oldDoc._attachments.myFile.content_type\n );\n return oldDoc;\n }\n}\n"})}),"\n",(0,o.jsx)(n.h2,{id:"migration-on-multi-tab-in-browsers",children:"Migration on multi-tab in browsers"}),"\n",(0,o.jsxs)(n.p,{children:["If you use RxDB in a multiInstance environment, like a browser, it will ensure that exactly one tab is running a migration of a collection.\nAlso the ",(0,o.jsx)(n.code,{children:"migrationState.$"})," events are emitted between browser tabs."]}),"\n",(0,o.jsx)(n.h2,{id:"migration-and-replication",children:"Migration and Replication"}),"\n",(0,o.jsxs)(n.p,{children:["If you use any of the ",(0,o.jsx)(n.a,{href:"/replication.html",children:"RxReplication"})," plugins, the migration will also run on the internal replication-state storage. It will migrate all ",(0,o.jsx)(n.code,{children:"assumedMasterState"})," documents\nso that after the migration is done, you do not have to re-run the replication from scratch.\nRxDB assumes that you run the exact same migration on the servers and the clients. Notice that the replication ",(0,o.jsx)(n.code,{children:"pull-checkpoint"})," will not be migrated. Your backend must be compatible with pull-checkpoints of older versions."]}),"\n",(0,o.jsx)(n.h2,{id:"migration-should-be-run-on-all-database-instances",children:"Migration should be run on all database instances"}),"\n",(0,o.jsxs)(n.p,{children:["If you have multiple database instances (for example, if you are running replication inside of a ",(0,o.jsx)(n.a,{href:"/rx-storage-worker.html",children:"Worker"})," or ",(0,o.jsx)(n.a,{href:"/rx-storage-shared-worker.html",children:"SharedWorker"})," and have created a database instance inside of the worker), schema migration should be started on all database instances. All instances must know about all migration strategies and any updated schema versions."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var a=t(6540);const o={},s=a.createContext(o);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/dc42ba65.77d77818.js b/docs/assets/js/dc42ba65.77d77818.js new file mode 100644 index 00000000000..91968de76ee --- /dev/null +++ b/docs/assets/js/dc42ba65.77d77818.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4962],{1781:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>a,metadata:()=>r,toc:()=>p});const r=JSON.parse('{"id":"key-compression","title":"Key Compression","description":"With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.","source":"@site/docs/key-compression.md","sourceDirName":".","slug":"/key-compression.html","permalink":"/key-compression.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Key Compression","slug":"key-compression.html"},"sidebar":"tutorialSidebar","previous":{"title":"Encryption","permalink":"/encryption.html"},"next":{"title":"Logger \ud83d\udc51","permalink":"/logger.html"}}');var t=n(4848),o=n(8453),i=n(7580);const a={title:"Key Compression",slug:"key-compression.html"},l="Key Compression",c={},p=[{value:"Enable key compression",id:"enable-key-compression",level:2},{value:"Wrap your RxStorage with the key compression plugin",id:"wrap-your-rxstorage-with-the-key-compression-plugin",level:3},{value:"Create an RxDatabase",id:"create-an-rxdatabase",level:3},{value:"Create a compressed RxCollection",id:"create-a-compressed-rxcollection",level:3}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"key-compression",children:"Key Compression"})}),"\n",(0,t.jsxs)(s.p,{children:["With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.\nFor compression the npm module ",(0,t.jsx)(s.a,{href:"https://github.com/pubkey/jsonschema-key-compression",children:"jsonschema-key-compression"})," is used.\nIt compresses json-data based on its json-schema while still having valid json. It works by compressing long attribute-names into smaller ones and backwards."]}),"\n",(0,t.jsxs)(s.p,{children:["The compression and decompression happens internally, so when you work with a ",(0,t.jsx)(s.code,{children:"RxDocument"}),", you can access any property like normal."]}),"\n",(0,t.jsx)(s.h2,{id:"enable-key-compression",children:"Enable key compression"}),"\n",(0,t.jsxs)(s.p,{children:["The key compression plugin is a wrapper around any other ",(0,t.jsx)(s.a,{href:"/rx-storage.html",children:"RxStorage"}),"."]}),"\n",(0,t.jsxs)(i.g,{children:[(0,t.jsx)(s.h3,{id:"wrap-your-rxstorage-with-the-key-compression-plugin",children:"Wrap your RxStorage with the key compression plugin"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-ts",children:"import { wrappedKeyCompressionStorage } from 'rxdb/plugins/key-compression';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst storageWithKeyCompression = wrappedKeyCompressionStorage({\n storage: getRxStorageDexie()\n});\n"})}),(0,t.jsx)(s.h3,{id:"create-an-rxdatabase",children:"Create an RxDatabase"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-ts",children:"import { createRxDatabase } from 'rxdb/plugins/core';\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: storageWithKeyCompression\n});\n"})}),(0,t.jsx)(s.h3,{id:"create-a-compressed-rxcollection",children:"Create a compressed RxCollection"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-ts",children:"\nconst mySchema = {\n keyCompression: true, // set this to true, to enable the keyCompression\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100 // <- the primary key must have set maxLength\n }\n /* ... */\n }\n};\nawait db.addCollections({\n docs: {\n schema: mySchema\n }\n});\n"})})]})]})}function m(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},7580:(e,s,n)=>{n.d(s,{g:()=>t});var r=n(4848);function t(e){const s=[];let n=null;return e.children.forEach((e=>{e.props.id?(n&&s.push(n),n={headline:e,paragraphs:[]}):n&&n.paragraphs.push(e)})),n&&s.push(n),(0,r.jsx)("div",{style:o.stepsContainer,children:s.map(((e,s)=>(0,r.jsxs)("div",{style:o.stepWrapper,children:[(0,r.jsxs)("div",{style:o.stepIndicator,children:[(0,r.jsxs)("div",{style:o.stepNumber,children:[s+1,"."]}),(0,r.jsx)("div",{style:o.verticalLine})]}),(0,r.jsxs)("div",{style:o.stepContent,children:[(0,r.jsx)("div",{children:e.headline}),e.paragraphs.map(((e,s)=>(0,r.jsx)("div",{style:o.item,children:e},s)))]})]},s)))})}const o={stepsContainer:{display:"flex",flexDirection:"column"},stepWrapper:{display:"flex",alignItems:"stretch",marginBottom:"1rem",position:"relative",minWidth:0},stepIndicator:{position:"relative",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",width:"32px",marginRight:"1rem",minWidth:0},stepNumber:{width:"32px",height:"32px",borderRadius:"50%",backgroundColor:"var(--color-middle)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontWeight:"bold"},verticalLine:{position:"absolute",top:"32px",bottom:"0",left:"50%",width:"1px",background:"linear-gradient(to bottom, var(--color-middle) 0%, var(--color-middle) 80%, rgba(0,0,0,0) 100%)",transform:"translateX(-50%)"},stepContent:{flex:1,minWidth:0,overflowWrap:"break-word"},item:{marginTop:"0.5rem"}}},8453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>a});var r=n(6540);const t={},o=r.createContext(t);function i(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/dc42ba65.aeb3aca4.js b/docs/assets/js/dc42ba65.aeb3aca4.js deleted file mode 100644 index c7ae2cf6ddd..00000000000 --- a/docs/assets/js/dc42ba65.aeb3aca4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[4962],{1781:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>o,toc:()=>p});const o=JSON.parse('{"id":"key-compression","title":"Key Compression","description":"With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.","source":"@site/docs/key-compression.md","sourceDirName":".","slug":"/key-compression.html","permalink":"/key-compression.html","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Key Compression","slug":"key-compression.html"},"sidebar":"tutorialSidebar","previous":{"title":"Encryption","permalink":"/encryption.html"},"next":{"title":"Logger \ud83d\udc51","permalink":"/logger.html"}}');var r=s(4848),t=s(8453);const i={title:"Key Compression",slug:"key-compression.html"},a="Key Compression",c={},p=[{value:"Enable key compression",id:"enable-key-compression",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"key-compression",children:"Key Compression"})}),"\n",(0,r.jsxs)(n.p,{children:["With the key compression plugin, documents will be stored in a compressed format which saves up to 40% disc space.\nFor compression the npm module ",(0,r.jsx)(n.a,{href:"https://github.com/pubkey/jsonschema-key-compression",children:"jsonschema-key-compression"})," is used.\nIt compresses json-data based on its json-schema while still having valid json. It works by compressing long attribute-names into smaller ones and backwards."]}),"\n",(0,r.jsxs)(n.p,{children:["The compression and decompression happens internally, so when you work with a ",(0,r.jsx)(n.code,{children:"RxDocument"}),", you can access any property like normal."]}),"\n",(0,r.jsx)(n.h2,{id:"enable-key-compression",children:"Enable key compression"}),"\n",(0,r.jsxs)(n.p,{children:["The key compression plugin is a wrapper around any other ",(0,r.jsx)(n.a,{href:"/rx-storage.html",children:"RxStorage"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"You first have to wrap your RxStorage with the key compression plugin"}),"\n",(0,r.jsxs)(n.li,{children:["Then use that as ",(0,r.jsx)(n.code,{children:"RxStorage"})," when calling ",(0,r.jsx)(n.code,{children:"createRxDatabase()"})]}),"\n",(0,r.jsxs)(n.li,{children:["Then you have to enable the key compression by adding ",(0,r.jsx)(n.code,{children:"keyCompression: true"})," to your collection schema."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { wrappedKeyCompressionStorage } from 'rxdb/plugins/key-compression';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\n\nconst storageWithKeyCompression = wrappedKeyCompressionStorage({\n storage: getRxStorageDexie()\n});\n\nconst db = await createRxDatabase({\n name: 'mydatabase',\n storage: storageWithKeyCompression\n});\n\nconst mySchema = {\n keyCompression: true, // set this to true, to enable the keyCompression\n version: 0,\n primaryKey: 'id',\n type: 'object',\n properties: {\n id: {\n type: 'string',\n maxLength: 100 // <- the primary key must have set maxLength\n }\n /* ... */\n }\n};\n\n/* ... */\n"})})]})}function m(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var o=s(6540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/main.b9088f92.js b/docs/assets/js/main.64c0682a.js similarity index 66% rename from docs/assets/js/main.b9088f92.js rename to docs/assets/js/main.64c0682a.js index 8eb782c66dc..a46c714dba5 100644 --- a/docs/assets/js/main.b9088f92.js +++ b/docs/assets/js/main.64c0682a.js @@ -1,2 +1,2 @@ -/*! For license information please see main.b9088f92.js.LICENSE.txt */ -(self.webpackChunkrxdb=self.webpackChunkrxdb||[]).push([[8792],{99:(e,t,n)=>{"use strict";t.rA=t.Ks=void 0;const r=n(1635);var a=n(2562);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(a).default}});var o=n(7149);var i=n(2528);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},102:(e,t,n)=>{"use strict";n.d(t,{Nr:()=>p,w8:()=>h,B5:()=>S,Vd:()=>w,QB:()=>k,fW:()=>x,OF:()=>v,Y:()=>b});var r=n(6540),a=n(6347),o=n(2831),i=n(9493),l=n(214);function s(e){return Array.from(new Set(e))}var c=n(6351),u=n(1858),d=n(2306);function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}const f=(e,t)=>void 0!==e&&(0,l.ys)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||m(e.items,t))}function g(e,t){switch(e.type){case"category":return h(e,t)||void 0!==e.href&&!e.linkUnlisted||e.items.some((e=>g(e,t)));case"link":return!e.unlisted||h(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>g(e,t)))),[e,t])}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,l.ys)(o.href,n)||e(o.items))||"link"===o.type&&(0,l.ys)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function v(){const e=(0,d.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,c.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)((()=>s([t,n,a].filter(Boolean))),[t,n,a])}function x(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${s(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function S(e){let{route:t}=e;const n=(0,a.zy)(),r=(0,u.r)(),i=t.routes,l=i.find((e=>(0,a.B6)(n.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?r.docsSidebars[s]:void 0;return{docElement:(0,o.v)(i),sidebarName:s,sidebarItems:c}}},106:(e,t,n)=>{"use strict";function r(e,t,n){const r="tracking_event_";if(n){if(localStorage.getItem(r+e))return;localStorage.setItem(r+e,"1")}if(console.log("triggerTrackingEvent("+e+", "+t+", "+n+")"),"function"==typeof window.rdt)try{window.rdt("track","Lead",{transactionId:e+"-"+(new Date).getTime(),currency:"EUR",value:t})}catch(a){console.log("# Error on reddit trigger:"),console.dir(a)}if("function"==typeof window.gtag)try{window.gtag("event",e,{value:t,currency:"EUR"})}catch(a){console.log("# Error on google trigger:"),console.dir(a)}}n.d(t,{c:()=>r})},115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,c,u;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;for(u=e.entries();!(s=u.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof i.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof i.toString)return e.toString()===i.toString();if((l=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,c[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==c[s]&&"__v"!==c[s]&&"__o"!==c[s]||!e.$$typeof)&&!o(e[c[s]],i[c[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},166:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("set","page_path",t.pathname+t.search+t.hash),window.gtag("event","page_view")}))}}},204:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},214:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),a=n(8912),o=n(797);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.A,baseUrl:e})),[e])}},311:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},372:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540);const a=n(1934).A.canUseDOM?r.useLayoutEffect:r.useEffect},539:(e,t,n)=>{"use strict";n.d(t,{A:()=>c,T:()=>s});var r=n(6540),a=n(4848);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function l(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return o(l({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=l({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>X,vd:()=>G});var r=n(6540),a=n(5556),o=n.n(a),i=n(115),l=n.n(i),s=n(311),c=n.n(s),u=n(2833),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map((function(e){return g[e]})),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},k=Object.keys(x).reduce((function(e,t){return e[x[t]]=t,e}),{}),S=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=S(e,g.TITLE),n=S(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=S(e,"defaultTitle");return t||r||void 0},E=function(e){return S(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[g.BASE]})).map((function(e){return e[g.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a/g,">").replace(/"/g,""").replace(/'/g,"'")},I=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[x[n]||n]=e[n],t}),t)},M=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},F=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=D(n,a),[r.createElement(g.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=I(n),o=R(t);return a?"<"+e+' data-rh="true" '+a+">"+O(o,r)+"":"<"+e+' data-rh="true">'+O(o,r)+""}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return I(t)}};default:return{toComponent:function(){return M(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+O(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===L.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"")}),"")}(e,t,n)}}}},z=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=N(e.metaTags,v),o=N(t,b),i=N(n,y);return{priorityMethods:{toComponent:function(){return[].concat(M(g.META,a.priority),M(g.LINK,o.priority),M(g.SCRIPT,i.priority))},toString:function(){return F(g.META,a.priority,r)+" "+F(g.LINK,o.priority,r)+" "+F(g.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:F(g.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",a,r),link:F(g.LINK,u,r),meta:F(g.META,d,r),noscript:F(g.NOSCRIPT,o,r),script:F(g.SCRIPT,p,r),style:F(g.STYLE,i,r),title:F(g.TITLE,{title:s,titleAttributes:c},r)}},B=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?B:n.instances},add:function(e){(n.canUseDOM?B:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?B:n.instances).indexOf(e);(n.canUseDOM?B:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=z({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),q=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),H="undefined"!=typeof document,G=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);G.canUseDOM=H,G.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},G.defaultProps={context:{}},G.displayName="HelmetProvider";var W=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},K=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;V(g.BODY,e.bodyAttributes),V(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=R(e)),V(g.TITLE,t)}(u,d);var p={baseTag:W(g.BASE,n),linkTags:W(g.LINK,a),metaTags:W(g.META,o),noscriptTags:W(g.NOSCRIPT,i),scriptTags:W(g.SCRIPT,s),styleTags:W(g.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),l(e,f,m)},Q=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case g.TITLE:return p({},a,((t={})[r.type]=i,t.titleAttributes=p({},o),t));case g.BODY:return p({},a,{bodyAttributes:p({},o)});case g.HTML:return p({},a,{htmlAttributes:p({},o)});default:return p({},a,((n={})[r.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``} ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=h(r,J),l=Object.keys(i).reduce((function(e,t){return e[k[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case g.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,Z),a=p({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof $||(o=new $(o.context,o.instances)),o?r.createElement(Y,p({},a,{context:o.value,helmetData:void 0})):r.createElement(U.Consumer,null,(function(e){return r.createElement(Y,p({},a,{context:e}))}))},t}(r.Component);X.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},X.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},X.displayName="Helmet"},689:function(e){e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=a,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach((function(t){var n=e.filter((function(e){return e.contains(t)})).length>0;-1!==e.indexOf(t)||n||e.push(t)})),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var a=e.contentWindow;if(r=a.document,!a||!r)throw new Error("iframe inaccessible")}catch(o){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,a=!1,o=null,i=function i(){if(!a){a=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",i),r.getIframeContents(e,t,n))}catch(l){n()}}};e.addEventListener("load",i),o=setTimeout(i,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(r){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,(function(){return!0}),(function(e){r++,n.waitForIframes(e.querySelector("html"),(function(){--r||t()}))}),(function(e){e||t()}))}},{key:"forEachIframe",value:function(t,n,r){var a=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=t.querySelectorAll("iframe"),l=i.length,s=0;i=Array.prototype.slice.call(i);var c=function(){--l<=0&&o(s)};l||c(),i.forEach((function(t){e.matches(t,a.exclude)?c():a.onIframeReady(t,(function(e){n(t)&&(s++,r(e)),c()}),c)}))}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var a=!1,o=!1;return r.forEach((function(e,t){e.val===n&&(a=t,o=e.handled)})),this.compareNodeIframe(e,t,n)?(!1!==a||o?!1===a||o||(r[a].handled=!0):r.push({val:n,handled:!0}),!0):(!1===a&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var a=this;e.forEach((function(e){e.handled||a.getIframeContents(e.val,(function(e){a.createInstanceOnIframe(e).forEachNode(t,n,r)}))}))}},{key:"iterateThroughNodes",value:function(e,t,n,r,a){for(var o=this,i=this.createIterator(t,e,r),l=[],s=[],c=void 0,u=void 0,d=function(){var e=o.getIteratorNode(i);return u=e.prevNode,c=e.node};d();)this.iframes&&this.forEachIframe(t,(function(e){return o.checkIframeFilter(c,u,e,l)}),(function(t){o.createInstanceOnIframe(t).forEachNode(e,(function(e){return s.push(e)}),r)})),s.push(c);s.forEach((function(e){n(e)})),this.iframes&&this.handleOpenIframes(l,e,n,r),a()}},{key:"forEachNode",value:function(e,t,n){var r=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),i=o.length;i||a(),o.forEach((function(o){var l=function(){r.iterateThroughNodes(e,o,t,n,(function(){--i<=0&&a()}))};r.iframes?r.waitForIframes(o,l):l()}))}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var a=!1;return n.every((function(t){return!r.call(e,t)||(a=!0,!1)})),a}return!1}}]),e}(),o=function(){function o(e){t(this,o),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(o,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var a in t)if(t.hasOwnProperty(a)){var o=t[a],i="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(a):this.escapeStr(a),l="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==i&&""!==l&&(e=e.replace(new RegExp("("+this.escapeStr(i)+"|"+this.escapeStr(l)+")","gm"+n),r+"("+this.processSynomyms(i)+"|"+this.processSynomyms(l)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,(function(e){return"\\"===e.charAt(0)?"?":"\x01"}))).replace(/(?:\\)*\*/g,(function(e){return"\\"===e.charAt(0)?"*":"\x02"}))}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,(function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"}))}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105","A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010d","C\xc7\u0106\u010c","d\u0111\u010f","D\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119","E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012b","I\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142","L\u0141","n\xf1\u0148\u0144","N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014d","O\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159","R\u0158","s\u0161\u015b\u0219\u015f","S\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163","T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016b","U\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xff","Y\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017a","Z\u017d\u017b\u0179"]:["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010dC\xc7\u0106\u010c","d\u0111\u010fD\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012bI\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142L\u0141","n\xf1\u0148\u0144N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014dO\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159R\u0158","s\u0161\u015b\u0219\u015fS\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016bU\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xffY\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017aZ\u017d\u017b\u0179"],r=[];return e.split("").forEach((function(a){n.every((function(n){if(-1!==n.indexOf(a)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0}))})),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xa1\xbf",r=this.opt.accuracy,a="string"==typeof r?r:r.value,o="string"==typeof r?[]:r.limiters,i="";switch(o.forEach((function(e){i+="|"+t.escapeStr(e)})),a){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr(n)))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach((function(e){t.opt.separateWordSearch?e.split(" ").forEach((function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)})):e.trim()&&-1===n.indexOf(e)&&n.push(e)})),{keywords:n.sort((function(e,t){return t.length-e.length})),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort((function(e,t){return e.start-t.start})).forEach((function(e){var a=t.callNoMatchOnInvalidRanges(e,r),o=a.start,i=a.end;a.valid&&(e.start=o,e.length=i-o,n.push(e),r=i)})),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,a=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?a=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:a}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,a=!0,o=n.length,i=t-o,l=parseInt(e.start,10)-i;return(r=(l=l>o?o:l)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),l<0||r-l<0||l>o||r>o?(a=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(l,r).replace(/\s+/g,"")&&(a=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:l,end:r,valid:a}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,(function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})}),(function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}),(function(){e({value:n,nodes:r})}))}},{key:"matchesExclude",value:function(e){return a.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",a=e.splitText(t),o=a.splitText(n-t),i=document.createElement(r);return i.setAttribute("data-markjs","true"),this.opt.className&&i.setAttribute("class",this.opt.className),i.textContent=a.textContent,a.parentNode.replaceChild(i,a),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,a){var o=this;e.nodes.every((function(i,l){var s=e.nodes[l+1];if(void 0===s||s.start>t){if(!r(i.node))return!1;var c=t-i.start,u=(n>i.end?i.end:n)-i.start,d=e.value.substr(0,i.start),p=e.value.substr(u+i.start);if(i.node=o.wrapRangeInTextNode(i.node,c,u),e.value=d+p,e.nodes.forEach((function(t,n){n>=l&&(e.nodes[n].start>0&&n!==l&&(e.nodes[n].start-=u),e.nodes[n].end-=u)})),n-=u,a(i.node.previousSibling,i.start),!(n>i.end))return!1;t=i.end}return!0}))}},{key:"wrapMatches",value:function(e,t,n,r,a){var o=this,i=0===t?0:t+1;this.getTextNodes((function(t){t.nodes.forEach((function(t){t=t.node;for(var a=void 0;null!==(a=e.exec(t.textContent))&&""!==a[i];)if(n(a[i],t)){var l=a.index;if(0!==i)for(var s=1;s{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6193);function o(){return(0,r.useContext)(a.o)}},961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(2551)},1020:(e,t,n)=>{"use strict";var r=n(6540),a=Symbol.for("react.element"),o=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,l=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,s={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,o={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,r)&&!s.hasOwnProperty(r)&&(o[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===o[r]&&(o[r]=t[r]);return{$$typeof:a,type:e,key:c,ref:u,props:o,_owner:l.current}}t.Fragment=o,t.jsx=c,t.jsxs=c},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>C,yJ:()=>f,sC:()=>A,AO:()=>p});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";n.d(t,{A:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t,o=n?"".concat(a,": ").concat(n):a;throw new Error(o)}}},1635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>I,__assign:()=>o,__asyncDelegator:()=>E,__asyncGenerator:()=>_,__asyncValues:()=>C,__await:()=>S,__awaiter:()=>m,__classPrivateFieldGet:()=>P,__classPrivateFieldIn:()=>O,__classPrivateFieldSet:()=>L,__createBinding:()=>g,__decorate:()=>l,__disposeResources:()=>M,__esDecorate:()=>c,__exportStar:()=>b,__extends:()=>a,__generator:()=>h,__importDefault:()=>N,__importStar:()=>R,__makeTemplateObject:()=>T,__metadata:()=>f,__param:()=>s,__propKey:()=>d,__read:()=>v,__rest:()=>i,__rewriteRelativeImportExtension:()=>F,__runInitializers:()=>u,__setFunctionName:()=>p,__spread:()=>w,__spreadArray:()=>k,__spreadArrays:()=>x,__values:()=>y,default:()=>z});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var o=function(){return o=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=0;l--)(a=e[l])&&(i=(o<3?a(i):o>3?a(t,n,i):a(t,n))||i);return o>3&&i&&Object.defineProperty(t,n,i),i}function s(e,t){return function(n,r){t(n,r,e)}}function c(e,t,n,r,a,o){function i(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var l,s=r.kind,c="getter"===s?"get":"setter"===s?"set":"value",u=!t&&e?r.static?e:e.prototype:null,d=t||(u?Object.getOwnPropertyDescriptor(u,r.name):{}),p=!1,f=n.length-1;f>=0;f--){var m={};for(var h in r)m[h]="access"===h?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(p)throw new TypeError("Cannot add initializers after decoration has completed");o.push(i(e||null))};var g=(0,n[f])("accessor"===s?{get:d.get,set:d.set}:d[c],m);if("accessor"===s){if(void 0===g)continue;if(null===g||"object"!=typeof g)throw new TypeError("Object expected");(l=i(g.get))&&(d.get=l),(l=i(g.set))&&(d.set=l),(l=i(g.init))&&a.unshift(l)}else(l=i(g))&&("field"===s?a.unshift(l):d[c]=l)}u&&Object.defineProperty(u,r.name,d),p=!0}function u(e,t,n){for(var r=arguments.length>2,a=0;a0&&a[a.length-1])||6!==l[0]&&2!==l[0])){o=0;continue}if(3===l[0]&&(!a||l[1]>a[0]&&l[1]=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function v(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,a,o=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)i.push(r.value)}catch(l){a={error:l}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(a)throw a.error}}return i}function w(){for(var e=[],t=0;t1||l(e,t)}))},t&&(r[e]=t(r[e])))}function l(e,t){try{(n=a[e](t)).value instanceof S?Promise.resolve(n.value.v).then(s,c):u(o[0][2],n)}catch(r){u(o[0][3],r)}var n}function s(e){l("next",e)}function c(e){l("throw",e)}function u(e,t){e(t),o.shift(),o.length&&l(o[0][0],o[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,a){t[r]=e[r]?function(t){return(n=!n)?{value:S(e[r](t)),done:!1}:a?a(t):t}:a}}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=y(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,a){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,a,(t=e[n](t)).done,t.value)}))}}}function T(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var A=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t},j=function(e){return j=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},j(e)};function R(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=j(e),r=0;r{"use strict";n.d(t,{My:()=>T,f4:()=>ne});var r,a,o,i,l,s,c,u=n(6540),d=n(4164),p=Object.create,f=Object.defineProperty,m=Object.defineProperties,h=Object.getOwnPropertyDescriptor,g=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,y=Object.getOwnPropertySymbols,v=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable,k=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,S=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&k(e,n,t[n]);if(y)for(var n of y(t))x.call(t,n)&&k(e,n,t[n]);return e},_=(e,t)=>m(e,g(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&y)for(var r of y(e))t.indexOf(r)<0&&x.call(e,r)&&(n[r]=e[r]);return n},C=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=k.value.length,k=k.next){var _=k.value;if(t.length>e.length)return;if(!(_ instanceof a)){var E,C=1;if(y){if(!(E=o(x,S,e,b))||E.index>=e.length)break;var T=E.index,A=E.index+E[0].length,j=S;for(j+=k.value.length;T>=j;)j+=(k=k.next).value.length;if(S=j-=k.value.length,k.value instanceof a)continue;for(var R=k;R!==t.tail&&(jd.reach&&(d.reach=O);var I=k.prev;if(P&&(I=s(t,I,P),S+=P.length),c(t,I,C),k=s(t,I,new a(p,g?r.tokenize(N,g):N,v,N)),L&&s(t,k,L),C>1){var D={cause:p+","+m,reach:O};i(e,t,n,k.prev,S,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}();t.exports=n,n.default=n}},function(){return a||(0,r[b(r)[0]])((a={exports:{}}).exports,a),a.exports}),T=((e,t,n)=>(n=null!=e?p(v(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of b(t))w.call(e,a)||a===n||f(e,a,{get:()=>t[a],enumerable:!(r=h(t,a))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(C());T.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},T.languages.markup.tag.inside["attr-value"].inside.entity=T.languages.markup.entity,T.languages.markup.doctype.inside["internal-subset"].inside=T.languages.markup,T.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(T.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:T.languages[t]},n.cdata=/^$/i,{"included-cdata":{pattern://i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:T.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},T.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(T.languages.markup.tag,"addAttribute",{value:function(e,t){T.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:T.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),T.languages.html=T.languages.markup,T.languages.mathml=T.languages.markup,T.languages.svg=T.languages.markup,T.languages.xml=T.languages.extend("markup",{}),T.languages.ssml=T.languages.xml,T.languages.atom=T.languages.xml,T.languages.rss=T.languages.xml,o=T,i={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},s="(?:[^\\\\-]|"+(l=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",s=RegExp(s+"-"+s),c={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},o.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:s,inside:{escape:l,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":i,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:l}},"special-escape":i,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":c}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:l,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},T.languages.javascript=T.languages.extend("clike",{"class-name":[T.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),T.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,T.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:T.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:T.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:T.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:T.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:T.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),T.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:T.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),T.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),T.languages.markup&&(T.languages.markup.tag.addInlined("script","javascript"),T.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),T.languages.js=T.languages.javascript,T.languages.actionscript=T.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<>?>?|[!=]=?)=?|[~?@]/}),T.languages.actionscript["class-name"].alias="function",delete T.languages.actionscript.parameter,delete T.languages.actionscript["literal-property"],T.languages.markup&&T.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:T.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(T),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},a="doc-comment";if(o=e.languages[t]){var o,i=o[a];if((i=i||(o=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[a])instanceof RegExp&&(i=o[a]={pattern:i}),Array.isArray(i))for(var l=0,s=i.length;l|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(T),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(T),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,i=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(T),T.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:T.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},T.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function s(t,n,i){var s=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),c=0,u={},d=(s=l(s.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=c++,n="___"+i.toUpperCase()+"_"+r+"___")););return u[n]=e,n})).join(""),n,i),Object.keys(u));return c=0,function t(n){for(var o=0;o=d.length)return;var i,s,p,f,m,h,g,b=n[o];"string"==typeof b||"string"==typeof b.content?(i=d[c],-1!==(g=(h="string"==typeof b?b:b.content).indexOf(i))&&(++c,s=h.substring(0,g),m=u[i],p=void 0,(f={})["interpolation-punctuation"]=a,3===(f=e.tokenize(m,f)).length&&((p=[1,1]).push.apply(p,l(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,p)),p=new e.Token("interpolation",f,r.alias,m),f=h.substring(g+i.length),m=[],s&&m.push(s),m.push(p),f&&(t(h=[f]),m.push.apply(m,h)),"string"==typeof b?(n.splice.apply(n,[o,1].concat(m)),o+=m.length-1):b.content=m)):(g=b.content,Array.isArray(g)?t(g):t([g]))}}(s),new e.Token(i,s,"language-"+i,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var c={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in c&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(T),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(//g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(T),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(T),T.languages.n4js=T.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),T.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),T.languages.n4jsd=T.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}function i(t){for(var n=[],r=0;r"!==a.content[a.content.length-1].content&&n.push({tagName:l(a.content[0].content[1]),openedBraces:0}):0+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var l=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(l).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||i(e.tokens)}))}(T),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(T),T.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},T.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=T.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(T),T.languages.c=T.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),T.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),T.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},T.languages.c.string],char:T.languages.c.char,comment:T.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:T.languages.c}}}}),T.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete T.languages.c.boolean,T.languages.objectivec=T.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete T.languages.objectivec["class-name"],T.languages.objc=T.languages.objectivec,T.languages.reason=T.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),T.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete T.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,n=0;n<2;n++)t=t.replace(//g,(function(){return t}));t=t.replace(//g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(T),T.languages.go=T.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),T.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete T.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(T),T.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},T.languages.python["string-interpolation"].inside.interpolation.inside.rest=T.languages.python,T.languages.py=T.languages.python,T.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},T.languages.webmanifest=T.languages.json;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>A,duotoneDark:()=>j,duotoneLight:()=>R,github:()=>N,gruvboxMaterialDark:()=>K,gruvboxMaterialLight:()=>Q,jettwaveDark:()=>H,jettwaveLight:()=>G,nightOwl:()=>P,nightOwlLight:()=>L,oceanicNext:()=>D,okaidia:()=>M,oneDark:()=>W,oneLight:()=>V,palenight:()=>F,shadesOfPurple:()=>z,synthwave84:()=>B,ultramin:()=>$,vsDark:()=>U,vsLight:()=>q});var A={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},j={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},R={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},N={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},P={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},L={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},O="#c5a5c5",I="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:O}},{types:["attr-value"],style:{color:I}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:I}},{types:["punctuation"],style:{color:I}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:O}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},M={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},F={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},z={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},B={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},q={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},H={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},G={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},W={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},V={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},K={plain:{color:"#ebdbb2",backgroundColor:"#292828"},styles:[{types:["imports","class-name","maybe-class-name","constant","doctype","builtin","function"],style:{color:"#d8a657"}},{types:["property-access"],style:{color:"#7daea3"}},{types:["tag"],style:{color:"#e78a4e"}},{types:["attr-name","char","url","regex"],style:{color:"#a9b665"}},{types:["attr-value","string"],style:{color:"#89b482"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#ea6962"}},{types:["entity","number","symbol"],style:{color:"#d3869b"}}]},Q={plain:{color:"#654735",backgroundColor:"#f9f5d7"},styles:[{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#af2528"}},{types:["imports","class-name","maybe-class-name","constant","doctype","builtin"],style:{color:"#b4730e"}},{types:["string","attr-value"],style:{color:"#477a5b"}},{types:["property-access"],style:{color:"#266b79"}},{types:["function","attr-name","char","url"],style:{color:"#72761e"}},{types:["tag"],style:{color:"#b94c07"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["entity","number","symbol"],style:{color:"#924f79"}}]},Y=/\r\n|\r|\n/,J=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Z=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},X=e=>{const t=[[]],n=[e],r=[0],a=[e.length];let o=0,i=0,l=[];const s=[l];for(;i>-1;){for(;(o=r[i]++)0?c:["plain"],e=u):(c=Z(c,u.type),u.alias&&(c=Z(c,u.alias)),e=u.content),"string"!=typeof e){i++,t.push(c),n.push(e),r.push(0),a.push(e.length);continue}const d=e.split(Y),p=d.length;l.push({types:c,content:d[0]});for(let t=1;t{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:a}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=S(S({},e[t]),a);e[t]=n})),e}),{});return r.root=n,r.plain=_(S({},n),{backgroundColor:void 0}),r},te=({children:e,language:t,code:n,theme:r,prism:a})=>{const o=t.toLowerCase(),i=ee(r,o),l=(e=>(0,u.useCallback)((t=>{var n=t,{className:r,style:a,line:o}=n,i=E(n,["className","style","line"]);const l=_(S({},i),{className:(0,d.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(l.style=e.plain),"object"==typeof a&&(l.style=S(S({},l.style||{}),a)),l}),[e]))(i),s=(e=>{const t=(0,u.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,u.useCallback)((e=>{var n=e,{token:r,className:a,style:o}=n,i=E(n,["token","className","style"]);const l=_(S({},i),{className:(0,d.A)("token",...r.types,a),children:r.content,style:t(r)});return null!=o&&(l.style=S(S({},l.style||{}),o)),l}),[t])})(i),c=(({prism:e,code:t,grammar:n,language:r})=>(0,u.useMemo)((()=>{if(null==n)return X([t]);const a={code:t,grammar:n,language:r,tokens:[]};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(t,n),e.hooks.run("after-tokenize",a),X(a.tokens)}),[t,n,r,e]))({prism:a,language:o,code:n,grammar:a.languages[o]});return e({tokens:c,className:`prism-code language-${o}`,style:null!=i?i.root:{},getLineProps:l,getTokenProps:s})},ne=e=>(0,u.createElement)(te,_(S({},e),{prism:e.prism||T,theme:e.theme||U,code:e.code,language:e.language}))},1769:(e,t,n)=>{"use strict";n.d(t,{e3:()=>f,be:()=>d,Jx:()=>m});var r=n(6540),a=n(4164),o=n(7143),i=n(5313);function l(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(9030),c=n(797);var u=n(4848);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const l=function(e){const{siteConfig:t}=(0,c.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.hH)(),p=a?d(a,{absolute:!0}):void 0;return(0,u.jsxs)(o.A,{children:[t&&(0,u.jsx)("title",{children:l}),t&&(0,u.jsx)("meta",{property:"og:title",content:l}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),l=(0,a.A)(i,t);return(0,u.jsxs)(p.Provider,{value:l,children:[(0,u.jsx)(o.A,{children:(0,u.jsx)("html",{className:l})}),n]})}function m(e){let{children:t}=e;const n=l(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,a.A)(r,o),children:t})}},1858:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(6540),a=n(6849),o=n(4848);const i=r.createContext(null);function l(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new a.dV("DocsVersionProvider");return e}},1934:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},2077:(e,t,n)=>{"use strict";n.d(t,{P_:()=>i,kh:()=>o});var r=n(797),a=n(4332);function o(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}function i(e,t,n){void 0===t&&(t=a.W),void 0===n&&(n={});const r=o(e),i=r?.[t];if(!i&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return i}},2094:(e,t,n)=>{"use strict";n.r(t)},2306:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>c});var r=n(6540),a=n(6849),o=n(4848);const i=Symbol("EmptyContext"),l=r.createContext(i);function s(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(l.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new a.dV("DocsSidebarProvider");return e}},2528:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},2551:(e,t,n)=>{"use strict";var r=n(6540),a=n(9982);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n