Skip to content

Commit 2c48091

Browse files
authored
feat: engine and database info + opt-in for unwraped values in idb + new options system (#107)
* feat: engine and database info + opt-in for unwraped values in idb
1 parent b3f3632 commit 2c48091

24 files changed

+567
-353
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ It was time to do a full review and refactoring, which results in:
4949
- `.has()`, `.keys()` and `.size` are deprecated in `LocalStorage`. They will be removed in v9. They moved to the new `StorageMap` service.
5050
- `JSONSchemaNumeric` deprecated (will be removed in v9)
5151
- `LSGetItemsOptions` deprecated (not necessary anymore, will be removed in v9)
52-
- `LOCAL_STORAGE_PREFIX` and `prefix` option of `localStorageProviders()` deprecated (will be removed in v9))
52+
- `LOCAL_STORAGE_PREFIX` and `localStorageProviders()` deprecated (will be removed in v9). Moved to `StorageModule.forRoot()`
5353
- `setItemSubscribe()`, `removeItemSubscribe()` and `clearSubscribe()` deprecated (will be removed in v9)
5454

5555
### Reduced public API

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ Efficient client-side storage module for Angular apps and Progressive Wep Apps (
77
- **security**: validate data with a JSON Schema,
88
- **compatibility**: works around some browsers issues,
99
- **documentation**: API fully explained, and a changelog!
10-
- **maintenance**: the lib follows Angular LTS and anticipates the next Angular version,
1110
- **reference**: 1st Angular library for client-side storage according to [ngx.tools](https://ngx.tools/#/search?q=local%20storage).
1211

1312
## By the same author
@@ -52,6 +51,28 @@ npm install @ngx-pwa/local-storage@next
5251
npm install @ngx-pwa/local-storage@6
5352
```
5453

54+
*Since version 8*, this second step is:
55+
- not required for the lib to work,
56+
- **strongly recommended for all new applications**, as it allows interoperability
57+
and is future-proof, as it should become the default in a future version,
58+
- **prohibited in applications already using this lib and already deployed in production**,
59+
as it would break with previously stored data.
60+
61+
```ts
62+
import { StorageModule } from '@ngx-pwa/local-storage';
63+
64+
@NgModule({
65+
imports: [
66+
StorageModule.forRoot({
67+
IDBNoWrap: true,
68+
})
69+
]
70+
})
71+
export class AppModule {}
72+
```
73+
74+
**Must be done at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
75+
5576
### Upgrading
5677

5778
If you still use the old `angular-async-local-storage` package, or to update to new versions,
@@ -105,7 +126,8 @@ export class YourService {
105126
```
106127

107128
New *since version 8* of this lib, this service API follows the
108-
[native `Map` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map),
129+
[native `Map` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
130+
and the new upcoming standard [kv-storage API](https://github.com/WICG/kv-storage),
109131
except it's asynchronous via [RxJS `Observable`s](http://reactivex.io/rxjs/).
110132

111133
It does the same thing as the `LocalStorage` service, but also allows more advanced operations.

docs/COLLISION.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ but is not recommended as there was breaking changes in v8.
1717
For example:
1818

1919
```typescript
20-
import { localStorageProviders } from '@ngx-pwa/local-storage';
20+
import { StorageModule } from '@ngx-pwa/local-storage';
2121

2222
@NgModule({
23-
providers: [
24-
localStorageProviders({
23+
imports: [
24+
StorageModule.forRoot({
2525
IDBDBName: 'myAppStorage', // custom database name when in `indexedDB`
2626
LSPrefix: 'myapp_', // prefix when in `localStorage` fallback
2727
})

docs/INTEROPERABILITY.md

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,42 @@ as there are important things to do and to be aware of to achieve interoperabili
1919
Interoperability can be achieved:
2020
- **since v8 of this lib**,
2121
- **only for apps that haven't been deployed in production yet**,
22-
as v8 changed the storage system to achieve interoperability:
23-
- it won't work on data stored with this lib before v8, as it still uses the old storage system for backward compatibility,
24-
- changing configuration on the fly would mean to **lose all previously stored data**.
22+
as v8 uses the following opt-in option to allow interoperability:
23+
changing configuration on the fly would mean to **lose all previously stored data**.
2524

26-
## Configuration
25+
```ts
26+
import { StorageModule } from '@ngx-pwa/local-storage';
27+
28+
@NgModule({
29+
imports: [
30+
StorageModule.forRoot({
31+
IDBNoWrap: true,
32+
})
33+
]
34+
})
35+
export class AppModule {}
36+
```
2737

2838
Note:
2939
- it is an initialization step, so as mentioned in the examples below, **it must be done in `AppModule`**,
3040
- **never change these options in an app already deployed in production, as all previously stored data would be lost**.
3141

42+
## Configuration
43+
3244
### `indexedDB` database and object store names
3345

3446
When storing in `indexedDB`, names are used for the database and the object store,
3547
so you will need that all APIs use the same names.
3648

37-
Option 1: keep the config of this lib and change the names in the other APIs,
38-
by using the default values exported by the lib:
39-
40-
```typescript
41-
import { DEFAULT_IDB_DB_NAME, DEFAULT_IDB_STORE_NAME } from '@ngx-pwa/local-storage';
42-
```
43-
44-
Option 2: change this lib config, according to your other APIs:
49+
- Option 1 (recommended): change this lib config, according to your other APIs:
4550

46-
```typescript
47-
import { localStorageProviders } from '@ngx-pwa/local-storage';
51+
```ts
52+
import { StorageModule } from '@ngx-pwa/local-storage';
4853

4954
@NgModule({
50-
providers: [
51-
localStorageProviders({
55+
imports: [
56+
StorageModule.forRoot({
57+
IDBNoWrap: true,
5258
IDBDBName: 'customDataBaseName',
5359
IDBStoreName: 'customStoreName',
5460
})
@@ -57,36 +63,62 @@ import { localStorageProviders } from '@ngx-pwa/local-storage';
5763
export class AppModule {}
5864
```
5965

66+
- Option 2: keep the config of this lib and change the options in the other APIs,
67+
by using the values exported by the lib:
68+
69+
```ts
70+
if (this.storageMap.backingEngine === 'indexedDB') {
71+
const { database, store, version } = this.storageMap.backingStore;
72+
}
73+
```
74+
75+
This second option can be difficult to manage due to some browsers issues in some special contexts
76+
(Firefox private mode and Safari cross-origin iframes),
77+
as **the information may be wrong at initialization,**
78+
as the storage could fallback from `indexedDB` to `localStorage`
79+
only after a first read or write operation.
80+
6081
### `localStorage` prefix
6182

6283
In some cases (see the [browser support guide](./BROWSERS_SUPPORT)),
6384
`indexedDB` is not available, and libs fallback to `localStorage`.
6485
Some libs prefixes `localStorage` keys. This lib doesn't by default,
65-
but you can add a prefix:
86+
but you can add a prefix.
87+
88+
- Option 1 (recommended):
6689

6790
```typescript
68-
import { localStorageProviders } from '@ngx-pwa/local-storage';
91+
import { StorageModule } from '@ngx-pwa/local-storage';
6992

7093
@NgModule({
71-
providers: [
72-
localStorageProviders({
94+
imports: [
95+
StorageModule.forRoot({
7396
LSPrefix: 'myapp_',
7497
})
7598
]
7699
})
77100
export class AppModule {}
78101
```
79102

103+
- Option 2:
104+
105+
```ts
106+
if (this.storageMap.backingEngine === 'localStorage') {
107+
const { prefix } = this.storageMap.fallbackBackingStore;
108+
}
109+
```
110+
80111
### Example with `localforage`
81112

82113
Interoperability with `localforage` lib can be achieved with this config:
83114

84115
```typescript
85-
import { localStorageProviders } from '@ngx-pwa/local-storage';
116+
import { StorageModule } from '@ngx-pwa/local-storage';
86117

87118
@NgModule({
88-
providers: [
89-
localStorageProviders({
119+
imports: [
120+
StorageModule.forRoot({
121+
IDBNoWrap: true,
90122
LSPrefix: 'localforage/',
91123
IDBDBName: 'localforage',
92124
IDBStoreName: 'keyvaluepairs',
@@ -96,6 +128,28 @@ import { localStorageProviders } from '@ngx-pwa/local-storage';
96128
export class AppModule {}
97129
```
98130

131+
### Example with native `indexedDB`
132+
133+
Interoperability with native `indexedDB` can be achieved that way:
134+
135+
```ts
136+
if (this.storageMap.backingEngine === 'indexedDB') {
137+
138+
const { database, store, version } = this.storageMap.backingStore;
139+
140+
const dbRequest = indexedDB.open(database, version);
141+
142+
dbRequest.addEventListener('success', () => {
143+
144+
const store = dbRequest.result.transaction([store], 'readonly').objectStore(store);
145+
146+
const request = store.get(index);
147+
148+
});
149+
150+
}
151+
```
152+
99153
## Warnings
100154

101155
### `indexedDB` store
@@ -107,7 +161,7 @@ or when the version change (but this case doesn't happen in this lib).
107161
**If this step is missing, then all `indexedDB` operations in the lib will fail as the store will be missing.**
108162

109163
Then, you need to ensure:
110-
- you use the same database `version` as the lib (none or `1`),
164+
- you use the same database `version` as the lib (default to `1`),
111165
- the store is created:
112166
- by letting this lib to be initialized first (beware of concurrency issues),
113167
- or if another API is going first, it needs to take care of the creation of the store (with the same name).

docs/MIGRATION_TO_V8.md

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,6 @@ npm install @ngx-pwa/local-storage@next
4444
2. Start your project: problems will be seen at compilation.
4545
Or you could search for `getItem` as most breaking changes are about its options.
4646

47-
## New `indexedDB` store
48-
49-
To allow interoperability, the internal `indexedDB` storing system has changed.
50-
It is not a breaking change as the lib do it in a backward-compatible way:
51-
- when `indexedDB` storage is empty (new app users or data swiped), the new storage is used,
52-
- when `indexedDB` old storage is here, the lib stays on this one.
53-
54-
So it should not concern you, but as it is very sensitive change, we recommend
55-
**to test previously stored data is not lost before deploying in production**.
56-
57-
It's internal stuff, but it also means there is a transition phase where some of the users of your app
58-
will be on the new storage, and others will be on the old one.
59-
6047
## The bad part: breaking changes
6148

6249
**The following changes may require action from you**.
@@ -343,11 +330,11 @@ export class AppModule {}
343330

344331
Since v8:
345332
```typescript
346-
import { localStorageProviders } from '@ngx-pwa/local-storage';
333+
import { StorageModule } from '@ngx-pwa/local-storage';
347334

348335
@NgModule({
349-
providers: [
350-
localStorageProviders({
336+
imports: [
337+
StorageModule.forRoot({
351338
LSPrefix: 'myapp_', // Note the underscore
352339
IDBDBName: 'myapp_ngStorage',
353340
}),

projects/demo/src/app/app.module.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
3+
import { StorageModule } from '@ngx-pwa/local-storage';
34

45
import { AppComponent } from './app.component';
56

67
@NgModule({
7-
declarations: [
8-
AppComponent
9-
],
8+
declarations: [AppComponent],
109
imports: [
11-
BrowserModule
10+
BrowserModule,
11+
StorageModule.forRoot({
12+
IDBNoWrap: true,
13+
}),
1214
],
13-
providers: [],
1415
bootstrap: [AppComponent]
1516
})
1617
export class AppModule { }

projects/ivy/src/app/app.module.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import { NgModule } from '@angular/core';
33

44
import { AppComponent } from './app.component';
55

6+
// TODO: reintroduce `StorageModule.forRoot()`
67
@NgModule({
7-
declarations: [
8-
AppComponent
9-
],
8+
declarations: [AppComponent],
109
imports: [
1110
BrowserModule
1211
],

projects/localforage/src/app/app.module.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
3-
import { localStorageProviders } from '@ngx-pwa/local-storage';
3+
import { StorageModule } from '@ngx-pwa/local-storage';
44

55
import { AppComponent } from './app.component';
66
import { AppRoutingModule } from './app-routing.module';
@@ -14,13 +14,12 @@ import { HomeComponent } from './home/home.component';
1414
imports: [
1515
BrowserModule,
1616
AppRoutingModule,
17-
],
18-
providers: [
19-
localStorageProviders({
17+
StorageModule.forRoot({
2018
LSPrefix: 'localforage/',
19+
IDBNoWrap: true,
2120
IDBDBName: 'localforage',
2221
IDBStoreName: 'keyvaluepairs'
23-
})
22+
}),
2423
],
2524
bootstrap: [AppComponent]
2625
})

0 commit comments

Comments
 (0)