@ngx-pwa/local-storage 14.0.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{esm2020 → esm2022}/lib/databases/exceptions.mjs +2 -2
- package/esm2022/lib/databases/indexeddb-database.mjs +305 -0
- package/esm2022/lib/databases/local-database.mjs +67 -0
- package/esm2022/lib/databases/localstorage-database.mjs +158 -0
- package/esm2022/lib/databases/memory-database.mjs +84 -0
- package/{esm2020 → esm2022}/lib/providers.mjs +3 -3
- package/esm2022/lib/storage.module.mjs +40 -0
- package/esm2022/lib/storages/local-storage.service.mjs +81 -0
- package/esm2022/lib/storages/storage-map.service.mjs +293 -0
- package/esm2022/lib/tokens.mjs +59 -0
- package/esm2022/lib/validation/json-schema.mjs +5 -0
- package/esm2022/lib/validation/json-validator.mjs +244 -0
- package/esm2022/public-api.mjs +12 -0
- package/{fesm2020 → fesm2022}/ngx-pwa-local-storage.mjs +543 -553
- package/fesm2022/ngx-pwa-local-storage.mjs.map +1 -0
- package/lib/databases/indexeddb-database.d.ts +2 -2
- package/lib/databases/local-database.d.ts +1 -1
- package/lib/databases/localstorage-database.d.ts +3 -3
- package/lib/databases/memory-database.d.ts +2 -2
- package/lib/providers.d.ts +1 -1
- package/lib/storage.module.d.ts +2 -2
- package/lib/storages/local-storage.service.d.ts +3 -3
- package/lib/storages/storage-map.service.d.ts +6 -7
- package/lib/tokens.d.ts +1 -1
- package/lib/validation/json-schema.d.ts +8 -8
- package/lib/validation/json-validator.d.ts +1 -1
- package/package.json +10 -16
- package/public-api.d.ts +10 -10
- package/schematics/collection.json +1 -1
- package/schematics/migration.json +1 -1
- package/schematics/ng-add/index.d.ts +1 -1
- package/schematics/ng-add/index.js +7 -7
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/schema.json +2 -2
- package/schematics/ng-update/index.d.ts +1 -1
- package/schematics/ng-update/index.js +3 -3
- package/schematics/ng-update/index.js.map +1 -1
- package/schematics/utility/config.d.ts +1 -1
- package/schematics/utility/config.js +7 -7
- package/schematics/utility/module.d.ts +1 -1
- package/schematics/utility/module.js +6 -6
- package/schematics/utility/module.js.map +1 -1
- package/esm2020/lib/databases/indexeddb-database.mjs +0 -304
- package/esm2020/lib/databases/local-database.mjs +0 -66
- package/esm2020/lib/databases/localstorage-database.mjs +0 -160
- package/esm2020/lib/databases/memory-database.mjs +0 -83
- package/esm2020/lib/storage.module.mjs +0 -39
- package/esm2020/lib/storages/local-storage.service.mjs +0 -80
- package/esm2020/lib/storages/storage-map.service.mjs +0 -299
- package/esm2020/lib/tokens.mjs +0 -59
- package/esm2020/lib/validation/json-schema.mjs +0 -5
- package/esm2020/lib/validation/json-validator.mjs +0 -243
- package/esm2020/public-api.mjs +0 -12
- package/fesm2015/ngx-pwa-local-storage.mjs +0 -1432
- package/fesm2015/ngx-pwa-local-storage.mjs.map +0 -1
- package/fesm2020/ngx-pwa-local-storage.mjs.map +0 -1
- /package/{esm2020 → esm2022}/lib/storages/exceptions.mjs +0 -0
- /package/{esm2020 → esm2022}/ngx-pwa-local-storage.mjs +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tree } from
|
|
1
|
+
import { Tree } from "@angular-devkit/schematics";
|
|
2
2
|
export declare const packageName = "@ngx-pwa/local-storage";
|
|
3
3
|
export declare function getDependencyMajorVersion(name: string, host: Tree): number | undefined;
|
|
4
4
|
export declare function getAllMainPaths(host: Tree): Promise<string[]>;
|
|
@@ -13,7 +13,7 @@ exports.getAllMainPaths = exports.getDependencyMajorVersion = exports.packageNam
|
|
|
13
13
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
14
14
|
const dependencies_1 = require("@schematics/angular/utility/dependencies");
|
|
15
15
|
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
16
|
-
exports.packageName =
|
|
16
|
+
exports.packageName = "@ngx-pwa/local-storage";
|
|
17
17
|
function getDependencyMajorVersion(name, host) {
|
|
18
18
|
const dependency = (0, dependencies_1.getPackageJsonDependency)(host, name);
|
|
19
19
|
/* Throw if Angular is not installed */
|
|
@@ -22,7 +22,7 @@ function getDependencyMajorVersion(name, host) {
|
|
|
22
22
|
}
|
|
23
23
|
/* Remove semver signs if present and keep only the first number (major) */
|
|
24
24
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
25
|
-
return Number.parseInt(dependency.version.replace(
|
|
25
|
+
return Number.parseInt(dependency.version.replace("~", "").replace("^", "").split(".")[0], 10);
|
|
26
26
|
}
|
|
27
27
|
exports.getDependencyMajorVersion = getDependencyMajorVersion;
|
|
28
28
|
function getAllMainPaths(host) {
|
|
@@ -32,15 +32,15 @@ function getAllMainPaths(host) {
|
|
|
32
32
|
/* Loop on all projects configured in angular.json */
|
|
33
33
|
workspace.projects.forEach((project) => {
|
|
34
34
|
/* The schematic only work with applications (not librairies) */
|
|
35
|
-
if (project.extensions[
|
|
35
|
+
if (project.extensions["projectType"] === "application") {
|
|
36
36
|
/* Get `main` option in angular.json project config */
|
|
37
|
-
const buildTarget = project.targets.get(
|
|
38
|
-
const e2eTarget = project.targets.get(
|
|
37
|
+
const buildTarget = project.targets.get("build");
|
|
38
|
+
const e2eTarget = project.targets.get("e2e");
|
|
39
39
|
if (buildTarget) {
|
|
40
|
-
if (!buildTarget.options || !buildTarget.options[
|
|
40
|
+
if (!buildTarget.options || !buildTarget.options["main"]) {
|
|
41
41
|
throw new schematics_1.SchematicsException(`angular.json config is broken, can't find 'architect.build.options.main' in one or more projects`);
|
|
42
42
|
}
|
|
43
|
-
mainPaths.push(buildTarget.options[
|
|
43
|
+
mainPaths.push(buildTarget.options["main"]);
|
|
44
44
|
}
|
|
45
45
|
else if (!e2eTarget) {
|
|
46
46
|
/* In old CLI projects, e2e where distinct applications project, we don't need to throw for them */
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.updateModuleToV9 = exports.updateModule = void 0;
|
|
4
4
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const typescript_1 = require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript");
|
|
5
6
|
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
|
|
6
7
|
const ng_ast_utils_1 = require("@schematics/angular/utility/ng-ast-utils");
|
|
7
|
-
const typescript_1 = require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript");
|
|
8
8
|
const config_1 = require("./config");
|
|
9
9
|
/**
|
|
10
10
|
* @param mainPath Path of the project `main.ts` file
|
|
@@ -15,7 +15,7 @@ function getAppModule(host, mainPath) {
|
|
|
15
15
|
if (!host.exists(appModulePath)) {
|
|
16
16
|
throw new schematics_1.SchematicsException(`Can't find AppModule`);
|
|
17
17
|
}
|
|
18
|
-
const appModuleFile = host.read(appModulePath).toString(
|
|
18
|
+
const appModuleFile = host.read(appModulePath).toString("utf-8");
|
|
19
19
|
return { appModulePath, appModuleFile };
|
|
20
20
|
}
|
|
21
21
|
function updateAppModule(host, appModulePath, appModuleFile, storageModuleName) {
|
|
@@ -36,10 +36,10 @@ function updateModule(mainPath) {
|
|
|
36
36
|
return (host) => {
|
|
37
37
|
const { appModulePath, appModuleFile } = getAppModule(host, mainPath);
|
|
38
38
|
/* If `IDBNoWrap` is already set, it **must not** be changed, otherwise previously stored data would be lost */
|
|
39
|
-
if (!appModuleFile.includes(
|
|
39
|
+
if (!appModuleFile.includes("IDBNoWrap")) {
|
|
40
40
|
if (appModuleFile.includes(config_1.packageName)) {
|
|
41
41
|
/* It's important to keep the current options, otherwise previously stored data would be lost */
|
|
42
|
-
const updatedAppModuleFile = appModuleFile.replace(/StorageModule.forRoot\({(.*)}\)/s,
|
|
42
|
+
const updatedAppModuleFile = appModuleFile.replace(/StorageModule.forRoot\({(.*)}\)/s, "StorageModule.forRoot({ IDBNoWrap: false,$1 })");
|
|
43
43
|
/* If the file is still the same, it means we didn't catch the module
|
|
44
44
|
* (for example, it can happen if the user aliased `StorageModule`) */
|
|
45
45
|
if (updatedAppModuleFile === appModuleFile) {
|
|
@@ -65,10 +65,10 @@ function updateModuleToV9(mainPath) {
|
|
|
65
65
|
return (host) => {
|
|
66
66
|
const { appModulePath, appModuleFile } = getAppModule(host, mainPath);
|
|
67
67
|
/* If `IDBNoWrap` is already set, it **must not** be changed, otherwise previously stored data would be lost */
|
|
68
|
-
if (!appModuleFile.includes(
|
|
68
|
+
if (!appModuleFile.includes("IDBNoWrap")) {
|
|
69
69
|
if (appModuleFile.includes(config_1.packageName)) {
|
|
70
70
|
/* It's important to keep the current options, otherwise previously stored data would be lost */
|
|
71
|
-
const updatedAppModuleFile = appModuleFile.replace(/StorageModule.forRoot\({(.*)}\)/s,
|
|
71
|
+
const updatedAppModuleFile = appModuleFile.replace(/StorageModule.forRoot\({(.*)}\)/s, "StorageModule.forRoot({ IDBNoWrap: false,$1 })");
|
|
72
72
|
/* If the file is still the same, it means we didn't catch the module
|
|
73
73
|
* (for example, it can happen if the user aliased `StorageModule`) */
|
|
74
74
|
if (updatedAppModuleFile === appModuleFile) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../../../projects/ngx-pwa/local-storage/schematics/utility/module.ts"],"names":[],"mappings":";;;AAAA,2DAA6E;AAC7E,qEAA0E;AAE1E,2EAA4E;AAC5E
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../../../projects/ngx-pwa/local-storage/schematics/utility/module.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import { Injectable, inject } from '@angular/core';
|
|
2
|
-
import { ReplaySubject, fromEvent, of, throwError, race } from 'rxjs';
|
|
3
|
-
import { map, mergeMap, first, takeWhile, tap } from 'rxjs/operators';
|
|
4
|
-
import { IDB_DB_NAME, IDB_STORE_NAME, IDB_DB_VERSION, IDB_NO_WRAP } from '../tokens';
|
|
5
|
-
import { IDBBrokenError } from './exceptions';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
export class IndexedDBDatabase {
|
|
8
|
-
constructor() {
|
|
9
|
-
/**
|
|
10
|
-
* `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
|
|
11
|
-
* even after the connection success event happened
|
|
12
|
-
*/
|
|
13
|
-
this.database = new ReplaySubject(1);
|
|
14
|
-
/**
|
|
15
|
-
* Index used when wrapping value. *For backward compatibility only.*
|
|
16
|
-
*/
|
|
17
|
-
this.wrapIndex = 'value';
|
|
18
|
-
this.dbName = inject(IDB_DB_NAME);
|
|
19
|
-
this.storeName = inject(IDB_STORE_NAME);
|
|
20
|
-
this.dbVersion = inject(IDB_DB_VERSION);
|
|
21
|
-
this.noWrap = inject(IDB_NO_WRAP);
|
|
22
|
-
/* Connect to `indexedDB`, with prefix if provided by the user */
|
|
23
|
-
this.connect();
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Information about `indexedDB` connection. *Only useful for interoperability.*
|
|
27
|
-
* @returns `indexedDB` database name, store name and database version
|
|
28
|
-
*/
|
|
29
|
-
get backingStore() {
|
|
30
|
-
return {
|
|
31
|
-
database: this.dbName,
|
|
32
|
-
store: this.storeName,
|
|
33
|
-
version: this.dbVersion,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Number of items in our `indexedDB` database and object store
|
|
38
|
-
*/
|
|
39
|
-
get size() {
|
|
40
|
-
/* Open a transaction in read-only mode */
|
|
41
|
-
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
|
|
42
|
-
const { store, events } = transactionData;
|
|
43
|
-
/* Request to know the number of items */
|
|
44
|
-
const request = store.count();
|
|
45
|
-
/* Return the result */
|
|
46
|
-
return events.pipe(map(() => request.result));
|
|
47
|
-
}),
|
|
48
|
-
/* The observable will complete after the first value */
|
|
49
|
-
first());
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Gets an item value in our `indexedDB` store
|
|
53
|
-
* @param key The item's key
|
|
54
|
-
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
|
|
55
|
-
*/
|
|
56
|
-
get(key) {
|
|
57
|
-
/* Open a transaction in read-only mode */
|
|
58
|
-
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
|
|
59
|
-
const { store, events } = transactionData;
|
|
60
|
-
/* Request the value with the key provided by the user */
|
|
61
|
-
const request = store.get(key);
|
|
62
|
-
/* Listen events and return the result */
|
|
63
|
-
return events.pipe(map(() => {
|
|
64
|
-
if ((request.result !== undefined) && (request.result !== null)) {
|
|
65
|
-
/* Prior to v8, the value was wrapped in an `{ value: ...}` object */
|
|
66
|
-
if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
68
|
-
(request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
70
|
-
return request.result[this.wrapIndex];
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
/* Cast to the wanted type */
|
|
74
|
-
return request.result;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/* Return `undefined` if the value is empty */
|
|
78
|
-
return undefined;
|
|
79
|
-
}));
|
|
80
|
-
}),
|
|
81
|
-
/* The observable will complete after the first value */
|
|
82
|
-
first());
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Sets an item in our `indexedDB` store
|
|
86
|
-
* @param key The item's key
|
|
87
|
-
* @param data The item's value
|
|
88
|
-
* @returns An RxJS `Observable` to wait the end of the operation
|
|
89
|
-
*/
|
|
90
|
-
set(key, data) {
|
|
91
|
-
/* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
|
|
92
|
-
if (data === undefined) {
|
|
93
|
-
return this.delete(key);
|
|
94
|
-
}
|
|
95
|
-
/* Open a transaction in write mode */
|
|
96
|
-
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
|
|
97
|
-
const { store, events } = transactionData;
|
|
98
|
-
/* Prior to v8, data was wrapped in a `{ value: ... }` object */
|
|
99
|
-
const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
|
|
100
|
-
/* Add if the item is not existing yet, or update otherwise */
|
|
101
|
-
store.put(dataToStore, key);
|
|
102
|
-
/* Listen to events and return `undefined` as no value is expected */
|
|
103
|
-
return events.pipe(map(() => undefined));
|
|
104
|
-
}),
|
|
105
|
-
/* The observable will complete after the first value */
|
|
106
|
-
first());
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Deletes an item in our `indexedDB` store
|
|
110
|
-
* @param key The item's key
|
|
111
|
-
* @returns An RxJS `Observable` to wait the end of the operation
|
|
112
|
-
*/
|
|
113
|
-
delete(key) {
|
|
114
|
-
/* Open a transaction in write mode */
|
|
115
|
-
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
|
|
116
|
-
const { store, events } = transactionData;
|
|
117
|
-
/* Delete the item in store */
|
|
118
|
-
store.delete(key);
|
|
119
|
-
/* Listen to events and return `undefined` as no data is expected here */
|
|
120
|
-
return events.pipe(map(() => undefined));
|
|
121
|
-
}),
|
|
122
|
-
/* The observable will complete after the first value */
|
|
123
|
-
first());
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Deletes all items from our `indexedDB` objet store
|
|
127
|
-
* @returns An RxJS `Observable` to wait the end of the operation
|
|
128
|
-
*/
|
|
129
|
-
clear() {
|
|
130
|
-
/* Open a transaction in write mode */
|
|
131
|
-
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
|
|
132
|
-
const { store, events } = transactionData;
|
|
133
|
-
/* Delete all items in object store */
|
|
134
|
-
store.clear();
|
|
135
|
-
/* Listen to events and return `undefined` as no data is expected here */
|
|
136
|
-
return events.pipe(map(() => undefined));
|
|
137
|
-
}),
|
|
138
|
-
/* The observable will complete */
|
|
139
|
-
first());
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Get all the keys in our `indexedDB` store
|
|
143
|
-
* @returns An RxJS `Observable` iterating on each key
|
|
144
|
-
*/
|
|
145
|
-
keys() {
|
|
146
|
-
/* Open a transaction in read-only mode */
|
|
147
|
-
return this.transaction('readonly').pipe(
|
|
148
|
-
/* `first()` is used as the final operator in other methods to complete the `Observable`
|
|
149
|
-
* (as it all starts from a `ReplaySubject` which never ends),
|
|
150
|
-
* but as this method is iterating over multiple values, `first()` **must** be used here */
|
|
151
|
-
first(), mergeMap((transactionData) => {
|
|
152
|
-
const { store } = transactionData;
|
|
153
|
-
/* Open a cursor on the store
|
|
154
|
-
* Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
|
|
155
|
-
const request = store.openKeyCursor();
|
|
156
|
-
/* Listen to success event */
|
|
157
|
-
const success$ = fromEvent(request, 'success').pipe(
|
|
158
|
-
/* Stop the `Observable` when the cursor is `null` */
|
|
159
|
-
takeWhile(() => (request.result !== null)),
|
|
160
|
-
/* This lib only allows string keys, but user could have added other types of keys from outside
|
|
161
|
-
* It's OK to cast as the cursor as been tested in the previous operator */
|
|
162
|
-
map(() => request.result.key.toString()),
|
|
163
|
-
/* Iterate on the cursor */
|
|
164
|
-
tap(() => { request.result.continue(); }));
|
|
165
|
-
/* Listen to error event and if so, throw an error */
|
|
166
|
-
const error$ = this.listenError(request);
|
|
167
|
-
/* Choose the first event to occur */
|
|
168
|
-
return race([success$, error$]);
|
|
169
|
-
}));
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Check if a key exists in our `indexedDB` store
|
|
173
|
-
* @returns An RxJS `Observable` telling if the key exists or not
|
|
174
|
-
*/
|
|
175
|
-
has(key) {
|
|
176
|
-
/* Open a transaction in read-only mode */
|
|
177
|
-
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
|
|
178
|
-
const { store, events } = transactionData;
|
|
179
|
-
/* Check if the key exists in the store
|
|
180
|
-
* Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
|
|
181
|
-
*/
|
|
182
|
-
const request = store.getKey(key);
|
|
183
|
-
/* Listen to events and return `true` or `false` */
|
|
184
|
-
return events.pipe(map(() => (request.result !== undefined) ? true : false));
|
|
185
|
-
}),
|
|
186
|
-
/* The observable will complete */
|
|
187
|
-
first());
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Connects to `indexedDB` and creates the object store on first time
|
|
191
|
-
*/
|
|
192
|
-
connect() {
|
|
193
|
-
let request;
|
|
194
|
-
/* Connect to `indexedDB`
|
|
195
|
-
* Will fail in Safari cross-origin iframes
|
|
196
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
|
|
197
|
-
try {
|
|
198
|
-
/* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
|
|
199
|
-
request = indexedDB.open(this.dbName, this.dbVersion);
|
|
200
|
-
}
|
|
201
|
-
catch {
|
|
202
|
-
this.database.error(new IDBBrokenError());
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
/* Create store on first connection */
|
|
206
|
-
this.createStore(request);
|
|
207
|
-
/* Listen to success and error events */
|
|
208
|
-
const success$ = fromEvent(request, 'success');
|
|
209
|
-
const error$ = this.listenError(request);
|
|
210
|
-
/* Choose the first to occur */
|
|
211
|
-
race([success$, error$])
|
|
212
|
-
/* The observable will complete */
|
|
213
|
-
.pipe(first())
|
|
214
|
-
.subscribe({
|
|
215
|
-
next: () => {
|
|
216
|
-
/* Register the database connection in the `ReplaySubject` for further access */
|
|
217
|
-
this.database.next(request.result);
|
|
218
|
-
},
|
|
219
|
-
error: () => {
|
|
220
|
-
/* Firefox private mode issue: fallback storage if IndexedDb connection is failing
|
|
221
|
-
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
|
|
222
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
|
|
223
|
-
this.database.error(new IDBBrokenError());
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Create store on first use of `indexedDB`
|
|
229
|
-
* @param request `indexedDB` database opening request
|
|
230
|
-
*/
|
|
231
|
-
createStore(request) {
|
|
232
|
-
/* Listen to the event fired on first connection */
|
|
233
|
-
fromEvent(request, 'upgradeneeded')
|
|
234
|
-
/* The observable will complete */
|
|
235
|
-
.pipe(first())
|
|
236
|
-
.subscribe({
|
|
237
|
-
next: () => {
|
|
238
|
-
/* Check if the store already exists, to avoid error */
|
|
239
|
-
if (!request.result.objectStoreNames.contains(this.storeName)) {
|
|
240
|
-
/* Create the object store */
|
|
241
|
-
request.result.createObjectStore(this.storeName);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Open an `indexedDB` transaction and get our store
|
|
248
|
-
* @param mode `readonly` or `readwrite`
|
|
249
|
-
* @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
|
|
250
|
-
*/
|
|
251
|
-
transaction(mode) {
|
|
252
|
-
/* From the `indexedDB` connection, open a transaction and get the store */
|
|
253
|
-
return this.database
|
|
254
|
-
.pipe(mergeMap((database) => {
|
|
255
|
-
let transaction;
|
|
256
|
-
try {
|
|
257
|
-
transaction = database.transaction([this.storeName], mode);
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
/* The store could have been deleted from outside */
|
|
261
|
-
return throwError(() => error);
|
|
262
|
-
}
|
|
263
|
-
/* Get the store from the transaction */
|
|
264
|
-
const store = transaction.objectStore(this.storeName);
|
|
265
|
-
/* Listen transaction `complete` and `error` events */
|
|
266
|
-
const events = this.listenTransactionEvents(transaction);
|
|
267
|
-
return of({ store, events });
|
|
268
|
-
}));
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Listen errors on a transaction or request, and throw if trigerred
|
|
272
|
-
* @param transactionOrRequest `indexedDb` transaction or request to listen
|
|
273
|
-
* @returns An `Observable` listening to errors
|
|
274
|
-
*/
|
|
275
|
-
listenError(transactionOrRequest) {
|
|
276
|
-
return fromEvent(transactionOrRequest, 'error').pipe(
|
|
277
|
-
/* Throw on error to be able to catch errors in RxJS way.
|
|
278
|
-
* Here `event.target` must be used, as `transactionOrRequest.error` will be `null`
|
|
279
|
-
* if we are on the request and the error is only triggered later by the transaction */
|
|
280
|
-
mergeMap((event) => throwError(() => event.target.error)));
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Listen transaction `complete` and `error` events
|
|
284
|
-
* @param transaction Transaction to listen
|
|
285
|
-
* @returns An `Observable` listening to transaction `complete` and `error` events
|
|
286
|
-
*/
|
|
287
|
-
listenTransactionEvents(transaction) {
|
|
288
|
-
/* Listen to the `complete` event */
|
|
289
|
-
const complete$ = fromEvent(transaction, 'complete');
|
|
290
|
-
/* Listen to the `error` event */
|
|
291
|
-
const error$ = this.listenError(transaction);
|
|
292
|
-
/* Choose the first event to occur */
|
|
293
|
-
return race([complete$, error$]);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
IndexedDBDatabase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: IndexedDBDatabase, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
297
|
-
IndexedDBDatabase.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: IndexedDBDatabase, providedIn: 'root' });
|
|
298
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: IndexedDBDatabase, decorators: [{
|
|
299
|
-
type: Injectable,
|
|
300
|
-
args: [{
|
|
301
|
-
providedIn: 'root'
|
|
302
|
-
}]
|
|
303
|
-
}], ctorParameters: function () { return []; } });
|
|
304
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXhlZGRiLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXB3YS9sb2NhbC1zdG9yYWdlL3NyYy9saWIvZGF0YWJhc2VzL2luZGV4ZWRkYi1kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsYUFBYSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRixPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRFLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7QUFNOUMsTUFBTSxPQUFPLGlCQUFpQjtJQWlDNUI7UUFoQkE7OztXQUdHO1FBQ2dCLGFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBYyxDQUFDLENBQUMsQ0FBQztRQU9oRTs7V0FFRztRQUNnQixjQUFTLEdBQUcsT0FBTyxDQUFDO1FBSXJDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRWxDLGlFQUFpRTtRQUNqRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFakIsQ0FBQztJ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VyxDQUFDLENBQUM7UUFFN0MscUNBQXFDO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFFbkMsQ0FBQzs7OEdBbGJVLGlCQUFpQjtrSEFBakIsaUJBQWlCLGNBRmhCLE1BQU07MkZBRVAsaUJBQWlCO2tCQUg3QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgUmVwbGF5U3ViamVjdCwgZnJvbUV2ZW50LCBvZiwgdGhyb3dFcnJvciwgcmFjZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBtZXJnZU1hcCwgZmlyc3QsIHRha2VXaGlsZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBJREJfREJfTkFNRSwgSURCX1NUT1JFX05BTUUsIElEQl9EQl9WRVJTSU9OLCBJREJfTk9fV1JBUCB9IGZyb20gJy4uL3Rva2Vucyc7XG5pbXBvcnQgeyBJREJCcm9rZW5FcnJvciB9IGZyb20gJy4vZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSAnLi9sb2NhbC1kYXRhYmFzZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEluZGV4ZWREQkRhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWVcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkYk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgb2JqZWN0IHN0b3JlIG5hbWVcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzdG9yZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgZGF0YWJhc2UgdmVyc2lvbi4gTXVzdCBiZSBhbiB1bnNpZ25lZCAqKmludGVnZXIqKlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRiVmVyc2lvbjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBgaW5kZXhlZERCYCBkYXRhYmFzZSBjb25uZWN0aW9uLCB3cmFwcGVkIGluIGEgUnhKUyBgUmVwbGF5U3ViamVjdGAgdG8gYmUgYWJsZSB0byBhY2Nlc3MgdGhlIGNvbm5lY3Rpb25cbiAgICogZXZlbiBhZnRlciB0aGUgY29ubmVjdGlvbiBzdWNjZXNzIGV2ZW50IGhhcHBlbmVkXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGF0YWJhc2UgPSBuZXcgUmVwbGF5U3ViamVjdDxJREJEYXRhYmFzZT4oMSk7XG5cbiAgLyoqXG4gICAqIEZsYWcgdG8gbm90IHdyYXAgYGluZGV4ZWREQmAgdmFsdWVzIGZvciBpbnRlcm9wZXJhYmlsaXR5IG9yIHRvIHdyYXAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbm9XcmFwOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmRleCB1c2VkIHdoZW4gd3JhcHBpbmcgdmFsdWUuICpGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBvbmx5LipcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSB3cmFwSW5kZXggPSAndmFsdWUnO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuXG4gICAgdGhpcy5kYk5hbWUgPSBpbmplY3QoSURCX0RCX05BTUUpO1xuICAgIHRoaXMuc3RvcmVOYW1lID0gaW5qZWN0KElEQl9TVE9SRV9OQU1FKTtcbiAgICB0aGlzLmRiVmVyc2lvbiA9IGluamVjdChJREJfREJfVkVSU0lPTik7XG4gICAgdGhpcy5ub1dyYXAgPSBpbmplY3QoSURCX05PX1dSQVApO1xuXG4gICAgLyogQ29ubmVjdCB0byBgaW5kZXhlZERCYCwgd2l0aCBwcmVmaXggaWYgcHJvdmlkZWQgYnkgdGhlIHVzZXIgKi9cbiAgICB0aGlzLmNvbm5lY3QoKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEluZm9ybWF0aW9uIGFib3V0IGBpbmRleGVkREJgIGNvbm5lY3Rpb24uICpPbmx5IHVzZWZ1bCBmb3IgaW50ZXJvcGVyYWJpbGl0eS4qXG4gICAqIEByZXR1cm5zIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWUsIHN0b3JlIG5hbWUgYW5kIGRhdGFiYXNlIHZlcnNpb25cbiAgICovXG4gIGdldCBiYWNraW5nU3RvcmUoKTogeyBkYXRhYmFzZTogc3RyaW5nLCBzdG9yZTogc3RyaW5nLCB2ZXJzaW9uOiBudW1iZXIgfSB7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YWJhc2U6IHRoaXMuZGJOYW1lLFxuICAgICAgc3RvcmU6IHRoaXMuc3RvcmVOYW1lLFxuICAgICAgdmVyc2lvbjogdGhpcy5kYlZlcnNpb24sXG4gICAgfTtcblxuICB9XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBpdGVtcyBpbiBvdXIgYGluZGV4ZWREQmAgZGF0YWJhc2UgYW5kIG9iamVjdCBzdG9yZVxuICAgKi9cbiAgZ2V0IHNpemUoKTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUmVxdWVzdCB0byBrbm93IHRoZSBudW1iZXIgb2YgaXRlbXMgKi9cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmNvdW50KCk7XG5cbiAgICAgICAgLyogUmV0dXJuIHRoZSByZXN1bHQgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcCgoKSA9PiByZXF1ZXN0LnJlc3VsdCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGl0ZW0gdmFsdWUgaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGFuIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqL1xuICBnZXQoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVua25vd24gfCB1bmRlZmluZWQ+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUmVxdWVzdCB0aGUgdmFsdWUgd2l0aCB0aGUga2V5IHByb3ZpZGVkIGJ5IHRoZSB1c2VyICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5nZXQoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gZXZlbnRzIGFuZCByZXR1cm4gdGhlIHJlc3VsdCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpOiB1bmtub3duID0+IHtcblxuICAgICAgICAgIGlmICgocmVxdWVzdC5yZXN1bHQgIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0ICE9PSBudWxsKSkge1xuXG4gICAgICAgICAgICAvKiBQcmlvciB0byB2OCwgdGhlIHZhbHVlIHdhcyB3cmFwcGVkIGluIGFuIGB7IHZhbHVlOiAuLi59YCBvYmplY3QgKi9cbiAgICAgICAgICAgIGlmICghdGhpcy5ub1dyYXAgJiYgKHR5cGVvZiByZXF1ZXN0LnJlc3VsdCA9PT0gJ29iamVjdCcpICYmICh0aGlzLndyYXBJbmRleCBpbiByZXF1ZXN0LnJlc3VsdCkgJiZcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3NcbiAgICAgICAgICAgIChyZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF0gIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0W3RoaXMud3JhcEluZGV4XSAhPT0gbnVsbCkpIHtcblxuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzXG4gICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF07XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgLyogQ2FzdCB0byB0aGUgd2FudGVkIHR5cGUgKi9cbiAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QucmVzdWx0O1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKiBSZXR1cm4gYHVuZGVmaW5lZGAgaWYgdGhlIHZhbHVlIGlzIGVtcHR5ICovXG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICB9KSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYW4gaXRlbSBpbiBvdXIgYGluZGV4ZWREQmAgc3RvcmVcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgaXRlbSdzIHZhbHVlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBzZXQoa2V5OiBzdHJpbmcsIGRhdGE6IHVua25vd24pOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogU3RvcmluZyBgdW5kZWZpbmVkYCBpbiBgaW5kZXhlZERiYCBjYW4gY2F1c2UgaXNzdWVzIGluIHNvbWUgYnJvd3NlcnMgc28gcmVtb3ZpbmcgaXRlbSBpbnN0ZWFkICovXG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlKGtleSk7XG4gICAgfVxuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHdyaXRlIG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZHdyaXRlJykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBQcmlvciB0byB2OCwgZGF0YSB3YXMgd3JhcHBlZCBpbiBhIGB7IHZhbHVlOiAuLi4gfWAgb2JqZWN0ICovXG4gICAgICAgIGNvbnN0IGRhdGFUb1N0b3JlID0gdGhpcy5ub1dyYXAgPyBkYXRhIDogeyBbdGhpcy53cmFwSW5kZXhdOiBkYXRhIH07XG5cbiAgICAgICAgLyogQWRkIGlmIHRoZSBpdGVtIGlzIG5vdCBleGlzdGluZyB5ZXQsIG9yIHVwZGF0ZSBvdGhlcndpc2UgKi9cbiAgICAgICAgc3RvcmUucHV0KGRhdGFUb1N0b3JlLCBrZXkpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdW5kZWZpbmVkYCBhcyBubyB2YWx1ZSBpcyBleHBlY3RlZCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpID0+IHVuZGVmaW5lZCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGl0ZW0gaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQW4gUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gd3JpdGUgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkd3JpdGUnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIERlbGV0ZSB0aGUgaXRlbSBpbiBzdG9yZSAqL1xuICAgICAgICBzdG9yZS5kZWxldGUoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gZXZlbnRzIGFuZCByZXR1cm4gYHVuZGVmaW5lZGAgYXMgbm8gZGF0YSBpcyBleHBlY3RlZCBoZXJlICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXAoKCkgPT4gdW5kZWZpbmVkKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYWxsIGl0ZW1zIGZyb20gb3VyIGBpbmRleGVkREJgIG9iamV0IHN0b3JlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBjbGVhcigpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHdyaXRlIG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZHdyaXRlJykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBEZWxldGUgYWxsIGl0ZW1zIGluIG9iamVjdCBzdG9yZSAqL1xuICAgICAgICBzdG9yZS5jbGVhcigpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdW5kZWZpbmVkYCBhcyBubyBkYXRhIGlzIGV4cGVjdGVkIGhlcmUgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcCgoKSA9PiB1bmRlZmluZWQpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIHRoZSBrZXlzIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCBpdGVyYXRpbmcgb24gZWFjaCBrZXlcbiAgICovXG4gIGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICAvKiBgZmlyc3QoKWAgaXMgdXNlZCBhcyB0aGUgZmluYWwgb3BlcmF0b3IgaW4gb3RoZXIgbWV0aG9kcyB0byBjb21wbGV0ZSB0aGUgYE9ic2VydmFibGVgXG4gICAgICAgKiAoYXMgaXQgYWxsIHN0YXJ0cyBmcm9tIGEgYFJlcGxheVN1YmplY3RgIHdoaWNoIG5ldmVyIGVuZHMpLFxuICAgICAgICogYnV0IGFzIHRoaXMgbWV0aG9kIGlzIGl0ZXJhdGluZyBvdmVyIG11bHRpcGxlIHZhbHVlcywgYGZpcnN0KClgICoqbXVzdCoqIGJlIHVzZWQgaGVyZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogT3BlbiBhIGN1cnNvciBvbiB0aGUgc3RvcmVcbiAgICAgICAgICogQXZvaWQgaXNzdWVzIGxpa2UgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvNjkgKi9cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLm9wZW5LZXlDdXJzb3IoKTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gc3VjY2VzcyBldmVudCAqL1xuICAgICAgICBjb25zdCBzdWNjZXNzJCA9IGZyb21FdmVudChyZXF1ZXN0LCAnc3VjY2VzcycpLnBpcGUoXG4gICAgICAgICAgLyogU3RvcCB0aGUgYE9ic2VydmFibGVgIHdoZW4gdGhlIGN1cnNvciBpcyBgbnVsbGAgKi9cbiAgICAgICAgICB0YWtlV2hpbGUoKCkgPT4gKHJlcXVlc3QucmVzdWx0ICE9PSBudWxsKSksXG4gICAgICAgICAgLyogVGhpcyBsaWIgb25seSBhbGxvd3Mgc3RyaW5nIGtleXMsIGJ1dCB1c2VyIGNvdWxkIGhhdmUgYWRkZWQgb3RoZXIgdHlwZXMgb2Yga2V5cyBmcm9tIG91dHNpZGVcbiAgICAgICAgICAgKiBJdCdzIE9LIHRvIGNhc3QgYXMgdGhlIGN1cnNvciBhcyBiZWVuIHRlc3RlZCBpbiB0aGUgcHJldmlvdXMgb3BlcmF0b3IgKi9cbiAgICAgICAgICBtYXAoKCkgPT4gKHJlcXVlc3QucmVzdWx0IGFzIElEQkN1cnNvcikua2V5LnRvU3RyaW5nKCkpLFxuICAgICAgICAgIC8qIEl0ZXJhdGUgb24gdGhlIGN1cnNvciAqL1xuICAgICAgICAgIHRhcCgoKSA9PiB7IChyZXF1ZXN0LnJlc3VsdCBhcyBJREJDdXJzb3IpLmNvbnRpbnVlKCk7IH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBlcnJvciBldmVudCBhbmQgaWYgc28sIHRocm93IGFuIGVycm9yICovXG4gICAgICAgIGNvbnN0IGVycm9yJCA9IHRoaXMubGlzdGVuRXJyb3IocmVxdWVzdCk7XG5cbiAgICAgICAgLyogQ2hvb3NlIHRoZSBmaXJzdCBldmVudCB0byBvY2N1ciAqL1xuICAgICAgICByZXR1cm4gcmFjZShbc3VjY2VzcyQsIGVycm9yJF0pO1xuXG4gICAgICB9KSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBrZXkgZXhpc3RzIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCB0ZWxsaW5nIGlmIHRoZSBrZXkgZXhpc3RzIG9yIG5vdFxuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gcmVhZC1vbmx5IG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZG9ubHknKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIENoZWNrIGlmIHRoZSBrZXkgZXhpc3RzIGluIHRoZSBzdG9yZVxuICAgICAgICAgKiBGaXhlcyBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy82OVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmdldEtleShrZXkpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdHJ1ZWAgb3IgYGZhbHNlYCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpID0+IChyZXF1ZXN0LnJlc3VsdCAhPT0gdW5kZWZpbmVkKSA/IHRydWUgOiBmYWxzZSkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIGBpbmRleGVkREJgIGFuZCBjcmVhdGVzIHRoZSBvYmplY3Qgc3RvcmUgb24gZmlyc3QgdGltZVxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbm5lY3QoKTogdm9pZCB7XG5cbiAgICBsZXQgcmVxdWVzdDogSURCT3BlbkRCUmVxdWVzdDtcblxuICAgIC8qIENvbm5lY3QgdG8gYGluZGV4ZWREQmBcbiAgICAgKiBXaWxsIGZhaWwgaW4gU2FmYXJpIGNyb3NzLW9yaWdpbiBpZnJhbWVzXG4gICAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvNDJ9ICovXG4gICAgdHJ5IHtcblxuICAgICAgLyogRG8gTk9UIGV4cGxpY2l0IGB3aW5kb3dgIGhlcmUsIGFzIGBpbmRleGVkREJgIGNvdWxkIGJlIHVzZWQgZnJvbSBhIHdlYiB3b3JrZXIgdG9vICovXG4gICAgICByZXF1ZXN0ID0gaW5kZXhlZERCLm9wZW4odGhpcy5kYk5hbWUsIHRoaXMuZGJWZXJzaW9uKTtcblxuICAgIH0gY2F0Y2gge1xuXG4gICAgICB0aGlzLmRhdGFiYXNlLmVycm9yKG5ldyBJREJCcm9rZW5FcnJvcigpKTtcblxuICAgICAgcmV0dXJuO1xuXG4gICAgfVxuXG4gICAgLyogQ3JlYXRlIHN0b3JlIG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICB0aGlzLmNyZWF0ZVN0b3JlKHJlcXVlc3QpO1xuXG4gICAgLyogTGlzdGVuIHRvIHN1Y2Nlc3MgYW5kIGVycm9yIGV2ZW50cyAqL1xuICAgIGNvbnN0IHN1Y2Nlc3MkID0gZnJvbUV2ZW50KHJlcXVlc3QsICdzdWNjZXNzJyk7XG4gICAgY29uc3QgZXJyb3IkID0gdGhpcy5saXN0ZW5FcnJvcihyZXF1ZXN0KTtcblxuICAgIC8qIENob29zZSB0aGUgZmlyc3QgdG8gb2NjdXIgKi9cbiAgICByYWNlKFtzdWNjZXNzJCwgZXJyb3IkXSlcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgKi9cbiAgICAgIC5waXBlKGZpcnN0KCkpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICAgIC8qIFJlZ2lzdGVyIHRoZSBkYXRhYmFzZSBjb25uZWN0aW9uIGluIHRoZSBgUmVwbGF5U3ViamVjdGAgZm9yIGZ1cnRoZXIgYWNjZXNzICovXG4gICAgICAgICAgdGhpcy5kYXRhYmFzZS5uZXh0KHJlcXVlc3QucmVzdWx0KTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAvKiBGaXJlZm94IHByaXZhdGUgbW9kZSBpc3N1ZTogZmFsbGJhY2sgc3RvcmFnZSBpZiBJbmRleGVkRGIgY29ubmVjdGlvbiBpcyBmYWlsaW5nXG4gICAgICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD03ODE5ODJ9XG4gICAgICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy8yNn0gKi9cbiAgICAgICAgICB0aGlzLmRhdGFiYXNlLmVycm9yKG5ldyBJREJCcm9rZW5FcnJvcigpKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHN0b3JlIG9uIGZpcnN0IHVzZSBvZiBgaW5kZXhlZERCYFxuICAgKiBAcGFyYW0gcmVxdWVzdCBgaW5kZXhlZERCYCBkYXRhYmFzZSBvcGVuaW5nIHJlcXVlc3RcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVTdG9yZShyZXF1ZXN0OiBJREJPcGVuREJSZXF1ZXN0KTogdm9pZCB7XG5cbiAgICAvKiBMaXN0ZW4gdG8gdGhlIGV2ZW50IGZpcmVkIG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICBmcm9tRXZlbnQocmVxdWVzdCwgJ3VwZ3JhZGVuZWVkZWQnKVxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoKSA9PiB7XG5cbiAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgc3RvcmUgYWxyZWFkeSBleGlzdHMsIHRvIGF2b2lkIGVycm9yICovXG4gICAgICAgICAgaWYgKCFyZXF1ZXN0LnJlc3VsdC5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHRoaXMuc3RvcmVOYW1lKSkge1xuXG4gICAgICAgICAgICAvKiBDcmVhdGUgdGhlIG9iamVjdCBzdG9yZSAqL1xuICAgICAgICAgICAgcmVxdWVzdC5yZXN1bHQuY3JlYXRlT2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuXG4gICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogT3BlbiBhbiBgaW5kZXhlZERCYCB0cmFuc2FjdGlvbiBhbmQgZ2V0IG91ciBzdG9yZVxuICAgKiBAcGFyYW0gbW9kZSBgcmVhZG9ubHlgIG9yIGByZWFkd3JpdGVgXG4gICAqIEByZXR1cm5zIEFuIGBpbmRleGVkREJgIHRyYW5zYWN0aW9uIHN0b3JlIGFuZCBldmVudHMsIHdyYXBwZWQgaW4gYW4gUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gIHByb3RlY3RlZCB0cmFuc2FjdGlvbihtb2RlOiBJREJUcmFuc2FjdGlvbk1vZGUpOiBPYnNlcnZhYmxlPHtcbiAgICBzdG9yZTogSURCT2JqZWN0U3RvcmU7XG4gICAgZXZlbnRzOiBPYnNlcnZhYmxlPEV2ZW50PjtcbiAgfT4ge1xuXG4gICAgLyogRnJvbSB0aGUgYGluZGV4ZWREQmAgY29ubmVjdGlvbiwgb3BlbiBhIHRyYW5zYWN0aW9uIGFuZCBnZXQgdGhlIHN0b3JlICovXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2VcbiAgICAgIC5waXBlKG1lcmdlTWFwKChkYXRhYmFzZSkgPT4ge1xuXG4gICAgICAgIGxldCB0cmFuc2FjdGlvbjogSURCVHJhbnNhY3Rpb247XG5cbiAgICAgICAgdHJ5IHtcblxuICAgICAgICAgIHRyYW5zYWN0aW9uID0gZGF0YWJhc2UudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgbW9kZSk7XG5cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcblxuICAgICAgICAgICAgLyogVGhlIHN0b3JlIGNvdWxkIGhhdmUgYmVlbiBkZWxldGVkIGZyb20gb3V0c2lkZSAqL1xuICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IgYXMgRE9NRXhjZXB0aW9uKTtcblxuICAgICAgICB9XG5cbiAgICAgICAgLyogR2V0IHRoZSBzdG9yZSBmcm9tIHRoZSB0cmFuc2FjdGlvbiAqL1xuICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcblxuICAgICAgICAvKiBMaXN0ZW4gdHJhbnNhY3Rpb24gYGNvbXBsZXRlYCBhbmQgYGVycm9yYCBldmVudHMgKi9cbiAgICAgICAgY29uc3QgZXZlbnRzID0gdGhpcy5saXN0ZW5UcmFuc2FjdGlvbkV2ZW50cyh0cmFuc2FjdGlvbik7XG5cbiAgICAgICAgcmV0dXJuIG9mKHsgc3RvcmUsIGV2ZW50cyB9KTtcblxuICAgICAgfSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIGVycm9ycyBvbiBhIHRyYW5zYWN0aW9uIG9yIHJlcXVlc3QsIGFuZCB0aHJvdyBpZiB0cmlnZXJyZWRcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uT3JSZXF1ZXN0IGBpbmRleGVkRGJgIHRyYW5zYWN0aW9uIG9yIHJlcXVlc3QgdG8gbGlzdGVuXG4gICAqIEByZXR1cm5zIEFuIGBPYnNlcnZhYmxlYCBsaXN0ZW5pbmcgdG8gZXJyb3JzXG4gICAqL1xuICBwcm90ZWN0ZWQgbGlzdGVuRXJyb3IodHJhbnNhY3Rpb25PclJlcXVlc3Q6IElEQlRyYW5zYWN0aW9uIHwgSURCUmVxdWVzdCk6IE9ic2VydmFibGU8bmV2ZXI+IHtcblxuICAgIHJldHVybiBmcm9tRXZlbnQodHJhbnNhY3Rpb25PclJlcXVlc3QsICdlcnJvcicpLnBpcGUoXG4gICAgICAvKiBUaHJvdyBvbiBlcnJvciB0byBiZSBhYmxlIHRvIGNhdGNoIGVycm9ycyBpbiBSeEpTIHdheS5cbiAgICAgICAqIEhlcmUgYGV2ZW50LnRhcmdldGAgbXVzdCBiZSB1c2VkLCBhcyBgdHJhbnNhY3Rpb25PclJlcXVlc3QuZXJyb3JgIHdpbGwgYmUgYG51bGxgXG4gICAgICAgKiBpZiB3ZSBhcmUgb24gdGhlIHJlcXVlc3QgYW5kIHRoZSBlcnJvciBpcyBvbmx5IHRyaWdnZXJlZCBsYXRlciBieSB0aGUgdHJhbnNhY3Rpb24gKi9cbiAgICAgIG1lcmdlTWFwKChldmVudCkgPT4gdGhyb3dFcnJvcigoKSA9PiAoZXZlbnQudGFyZ2V0IGFzIElEQlRyYW5zYWN0aW9uIHwgSURCUmVxdWVzdCkuZXJyb3IpKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIHRyYW5zYWN0aW9uIGBjb21wbGV0ZWAgYW5kIGBlcnJvcmAgZXZlbnRzXG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbiBUcmFuc2FjdGlvbiB0byBsaXN0ZW5cbiAgICogQHJldHVybnMgQW4gYE9ic2VydmFibGVgIGxpc3RlbmluZyB0byB0cmFuc2FjdGlvbiBgY29tcGxldGVgIGFuZCBgZXJyb3JgIGV2ZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGxpc3RlblRyYW5zYWN0aW9uRXZlbnRzKHRyYW5zYWN0aW9uOiBJREJUcmFuc2FjdGlvbik6IE9ic2VydmFibGU8RXZlbnQ+IHtcblxuICAgIC8qIExpc3RlbiB0byB0aGUgYGNvbXBsZXRlYCBldmVudCAqL1xuICAgIGNvbnN0IGNvbXBsZXRlJCA9IGZyb21FdmVudCh0cmFuc2FjdGlvbiwgJ2NvbXBsZXRlJyk7XG5cbiAgICAvKiBMaXN0ZW4gdG8gdGhlIGBlcnJvcmAgZXZlbnQgKi9cbiAgICBjb25zdCBlcnJvciQgPSB0aGlzLmxpc3RlbkVycm9yKHRyYW5zYWN0aW9uKTtcblxuICAgIC8qIENob29zZSB0aGUgZmlyc3QgZXZlbnQgdG8gb2NjdXIgKi9cbiAgICByZXR1cm4gcmFjZShbY29tcGxldGUkLCBlcnJvciRdKTtcblxuICB9XG5cbn1cbiJdfQ==
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { inject, Injectable, PLATFORM_ID } from '@angular/core';
|
|
2
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
3
|
-
import { IndexedDBDatabase } from './indexeddb-database';
|
|
4
|
-
import { LocalStorageDatabase } from './localstorage-database';
|
|
5
|
-
import { MemoryDatabase } from './memory-database';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
/**
|
|
8
|
-
* Factory to create a storage according to browser support
|
|
9
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/main/docs/BROWSERS_SUPPORT.md}
|
|
10
|
-
*/
|
|
11
|
-
export function localDatabaseFactory() {
|
|
12
|
-
const platformId = inject(PLATFORM_ID);
|
|
13
|
-
/* When storage is fully disabled in browser (via the "Block all cookies" option),
|
|
14
|
-
* just trying to check `indexedDB` or `localStorage` variables causes a security exception.
|
|
15
|
-
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
|
|
16
|
-
*/
|
|
17
|
-
try {
|
|
18
|
-
// Do not explicit `window` here, as the global object is not the same in web workers
|
|
19
|
-
if (isPlatformBrowser(platformId) && (indexedDB !== undefined) && (indexedDB !== null) && ('open' in indexedDB)) {
|
|
20
|
-
/* Check:
|
|
21
|
-
* - if we are in a browser context (issue: server-side rendering)
|
|
22
|
-
* - it could exist but be `undefined` or `null`
|
|
23
|
-
* - it could exists but not having a working API
|
|
24
|
-
* Will be the case for:
|
|
25
|
-
* - All other browsers in normal mode
|
|
26
|
-
* - Chromium / Safari private mode, but in this case, data will be swiped when the user leaves the app */
|
|
27
|
-
return new IndexedDBDatabase();
|
|
28
|
-
}
|
|
29
|
-
else if (isPlatformBrowser(platformId)
|
|
30
|
-
&& (localStorage !== undefined) && (localStorage !== null) && ('getItem' in localStorage)) {
|
|
31
|
-
/* Check:
|
|
32
|
-
* - if we are in a browser context (issue: server-side rendering)
|
|
33
|
-
* - if `localStorage` exists (to be sure)
|
|
34
|
-
* - it could exists but not having a working API
|
|
35
|
-
* Will be the case for:
|
|
36
|
-
* - Safari cross-origin iframes, detected later in `IndexedDBDatabase.connect()`
|
|
37
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42}
|
|
38
|
-
* - Firefox private mode, but in this case, data will be swiped when the user leaves the app
|
|
39
|
-
* For Firefox, can only be detected later in `IndexedDBDatabase.connect()`
|
|
40
|
-
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
|
|
41
|
-
*/
|
|
42
|
-
return new LocalStorageDatabase();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
// Nothing to do
|
|
47
|
-
}
|
|
48
|
-
/* Will be the case for:
|
|
49
|
-
* - In browsers if storage has been fully disabled (via the "Block all cookies" option)
|
|
50
|
-
* - Server-side rendering
|
|
51
|
-
* - All other non-browser context
|
|
52
|
-
*/
|
|
53
|
-
return new MemoryDatabase();
|
|
54
|
-
}
|
|
55
|
-
export class LocalDatabase {
|
|
56
|
-
}
|
|
57
|
-
LocalDatabase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: LocalDatabase, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
58
|
-
LocalDatabase.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: LocalDatabase, providedIn: 'root', useFactory: localDatabaseFactory });
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: LocalDatabase, decorators: [{
|
|
60
|
-
type: Injectable,
|
|
61
|
-
args: [{
|
|
62
|
-
providedIn: 'root',
|
|
63
|
-
useFactory: localDatabaseFactory,
|
|
64
|
-
}]
|
|
65
|
-
}] });
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcHdhL2xvY2FsLXN0b3JhZ2Uvc3JjL2xpYi9kYXRhYmFzZXMvbG9jYWwtZGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR3BELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7QUFFbkQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQjtJQUVsQyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFdkM7OztPQUdHO0lBQ0gsSUFBSTtRQUVGLHFGQUFxRjtRQUNyRixJQUFJLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxFQUFFO1lBRS9HOzs7Ozs7cUhBTXlHO1lBQ3pHLE9BQU8sSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1NBRWhDO2FBQU0sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7ZUFDckMsQ0FBQyxZQUFZLEtBQUssU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksWUFBWSxDQUFDLEVBQUU7WUFFekY7Ozs7Ozs7Ozs7Y0FVRTtZQUNGLE9BQU8sSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1NBRW5DO0tBRUY7SUFBQyxNQUFNO1FBQ04sZ0JBQWdCO0tBQ2pCO0lBRUQ7Ozs7T0FJRztJQUNILE9BQU8sSUFBSSxjQUFjLEVBQUUsQ0FBQztBQUU5QixDQUFDO0FBTUQsTUFBTSxPQUFnQixhQUFhOzswR0FBYixhQUFhOzhHQUFiLGFBQWEsY0FIckIsTUFBTSxjQUNOLG9CQUFvQjsyRkFFWixhQUFhO2tCQUpsQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO29CQUNsQixVQUFVLEVBQUUsb0JBQW9CO2lCQUNqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSW5kZXhlZERCRGF0YWJhc2UgfSBmcm9tICcuL2luZGV4ZWRkYi1kYXRhYmFzZSc7XG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VEYXRhYmFzZSB9IGZyb20gJy4vbG9jYWxzdG9yYWdlLWRhdGFiYXNlJztcbmltcG9ydCB7IE1lbW9yeURhdGFiYXNlIH0gZnJvbSAnLi9tZW1vcnktZGF0YWJhc2UnO1xuXG4vKipcbiAqIEZhY3RvcnkgdG8gY3JlYXRlIGEgc3RvcmFnZSBhY2NvcmRpbmcgdG8gYnJvd3NlciBzdXBwb3J0XG4gKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFpbi9kb2NzL0JST1dTRVJTX1NVUFBPUlQubWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2NhbERhdGFiYXNlRmFjdG9yeSgpOiBMb2NhbERhdGFiYXNlIHtcblxuICBjb25zdCBwbGF0Zm9ybUlkID0gaW5qZWN0KFBMQVRGT1JNX0lEKTtcblxuICAvKiBXaGVuIHN0b3JhZ2UgaXMgZnVsbHkgZGlzYWJsZWQgaW4gYnJvd3NlciAodmlhIHRoZSBcIkJsb2NrIGFsbCBjb29raWVzXCIgb3B0aW9uKSxcbiAgICoganVzdCB0cnlpbmcgdG8gY2hlY2sgYGluZGV4ZWREQmAgb3IgYGxvY2FsU3RvcmFnZWAgdmFyaWFibGVzIGNhdXNlcyBhIHNlY3VyaXR5IGV4Y2VwdGlvbi5cbiAgICogUHJldmVudHMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvMTE4XG4gICAqL1xuICB0cnkge1xuXG4gICAgLy8gRG8gbm90IGV4cGxpY2l0IGB3aW5kb3dgIGhlcmUsIGFzIHRoZSBnbG9iYWwgb2JqZWN0IGlzIG5vdCB0aGUgc2FtZSBpbiB3ZWIgd29ya2Vyc1xuICAgIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKSAmJiAoaW5kZXhlZERCICE9PSB1bmRlZmluZWQpICYmIChpbmRleGVkREIgIT09IG51bGwpICYmICgnb3BlbicgaW4gaW5kZXhlZERCKSkge1xuXG4gICAgICAvKiBDaGVjazpcbiAgICAgICogLSBpZiB3ZSBhcmUgaW4gYSBicm93c2VyIGNvbnRleHQgKGlzc3VlOiBzZXJ2ZXItc2lkZSByZW5kZXJpbmcpXG4gICAgICAqIC0gaXQgY291bGQgZXhpc3QgYnV0IGJlIGB1bmRlZmluZWRgIG9yIGBudWxsYFxuICAgICAgKiAtIGl0IGNvdWxkIGV4aXN0cyBidXQgbm90IGhhdmluZyBhIHdvcmtpbmcgQVBJXG4gICAgICAqIFdpbGwgYmUgdGhlIGNhc2UgZm9yOlxuICAgICAgKiAtIEFsbCBvdGhlciBicm93c2VycyBpbiBub3JtYWwgbW9kZVxuICAgICAgKiAtIENocm9taXVtIC8gU2FmYXJpIHByaXZhdGUgbW9kZSwgYnV0IGluIHRoaXMgY2FzZSwgZGF0YSB3aWxsIGJlIHN3aXBlZCB3aGVuIHRoZSB1c2VyIGxlYXZlcyB0aGUgYXBwICovXG4gICAgICByZXR1cm4gbmV3IEluZGV4ZWREQkRhdGFiYXNlKCk7XG5cbiAgICB9IGVsc2UgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHBsYXRmb3JtSWQpXG4gICAgJiYgKGxvY2FsU3RvcmFnZSAhPT0gdW5kZWZpbmVkKSAmJiAobG9jYWxTdG9yYWdlICE9PSBudWxsKSAmJiAoJ2dldEl0ZW0nIGluIGxvY2FsU3RvcmFnZSkpIHtcblxuICAgICAgLyogQ2hlY2s6XG4gICAgICAqIC0gaWYgd2UgYXJlIGluIGEgYnJvd3NlciBjb250ZXh0IChpc3N1ZTogc2VydmVyLXNpZGUgcmVuZGVyaW5nKVxuICAgICAgKiAtIGlmIGBsb2NhbFN0b3JhZ2VgIGV4aXN0cyAodG8gYmUgc3VyZSlcbiAgICAgICogLSBpdCBjb3VsZCBleGlzdHMgYnV0IG5vdCBoYXZpbmcgYSB3b3JraW5nIEFQSVxuICAgICAgKiBXaWxsIGJlIHRoZSBjYXNlIGZvcjpcbiAgICAgICogLSBTYWZhcmkgY3Jvc3Mtb3JpZ2luIGlmcmFtZXMsIGRldGVjdGVkIGxhdGVyIGluIGBJbmRleGVkREJEYXRhYmFzZS5jb25uZWN0KClgXG4gICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzQyfVxuICAgICAgKiAtIEZpcmVmb3ggcHJpdmF0ZSBtb2RlLCBidXQgaW4gdGhpcyBjYXNlLCBkYXRhIHdpbGwgYmUgc3dpcGVkIHdoZW4gdGhlIHVzZXIgbGVhdmVzIHRoZSBhcHBcbiAgICAgICogRm9yIEZpcmVmb3gsIGNhbiBvbmx5IGJlIGRldGVjdGVkIGxhdGVyIGluIGBJbmRleGVkREJEYXRhYmFzZS5jb25uZWN0KClgXG4gICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTc4MTk4Mn1cbiAgICAgICovXG4gICAgICByZXR1cm4gbmV3IExvY2FsU3RvcmFnZURhdGFiYXNlKCk7XG5cbiAgICB9XG5cbiAgfSBjYXRjaCB7XG4gICAgLy8gTm90aGluZyB0byBkb1xuICB9XG5cbiAgLyogV2lsbCBiZSB0aGUgY2FzZSBmb3I6XG4gICAqIC0gSW4gYnJvd3NlcnMgaWYgc3RvcmFnZSBoYXMgYmVlbiBmdWxseSBkaXNhYmxlZCAodmlhIHRoZSBcIkJsb2NrIGFsbCBjb29raWVzXCIgb3B0aW9uKVxuICAgKiAtIFNlcnZlci1zaWRlIHJlbmRlcmluZ1xuICAgKiAtIEFsbCBvdGhlciBub24tYnJvd3NlciBjb250ZXh0XG4gICAqL1xuICByZXR1cm4gbmV3IE1lbW9yeURhdGFiYXNlKCk7XG5cbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG4gIHVzZUZhY3Rvcnk6IGxvY2FsRGF0YWJhc2VGYWN0b3J5LFxufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2NhbERhdGFiYXNlIHtcblxuICBhYnN0cmFjdCByZWFkb25seSBzaXplOiBPYnNlcnZhYmxlPG51bWJlcj47XG5cbiAgYWJzdHJhY3QgZ2V0KGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmtub3duIHwgdW5kZWZpbmVkPjtcbiAgYWJzdHJhY3Qgc2V0KGtleTogc3RyaW5nLCBkYXRhOiB1bmtub3duKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+O1xuICBhYnN0cmFjdCBkZWxldGUoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPjtcbiAgYWJzdHJhY3Qga2V5cygpOiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIGFic3RyYWN0IGhhcyhrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj47XG5cbn1cbiJdfQ==
|