Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@v2

# Sets up Node and an .npmrc file. This is the official Github supported way to set up node.
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: "12"
registry-url: "https://registry.npmjs.org"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v2

# Sets up Node and an .npmrc file. This is the official Github supported way to set up node.
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: "12"
registry-url: "https://registry.npmjs.org"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/objectstoreprovider",
"version": "0.7.2",
"version": "0.8.0",
"description": "A cross-browser object store library",
"author": "Mukundan Kavanur Kidambi <[email protected]>",
"scripts": {
Expand Down
64 changes: 54 additions & 10 deletions src/IndexedDbProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
TransactionLockHelper,
} from "./TransactionLockHelper";
import { LogWriter } from "./LogWriter";
import { IDBGetAllRecordsOptions } from "./types/extended-idb";

const IndexPrefix = "nsp_i_";

Expand All @@ -74,6 +75,14 @@ declare global {
}
}

export interface IDBConfigs {
useGetAllRecordsForGetRange: boolean;
}

const defaultIDBConfigs: IDBConfigs = {
useGetAllRecordsForGetRange: false,
};

// The DbProvider implementation for IndexedDB. This one is fairly straightforward since the library's access patterns pretty
// closely mirror IndexedDB's. We mostly do a lot of wrapping of the APIs into JQuery promises and have some fancy footwork to
// do semi-automatic schema upgrades.
Expand All @@ -93,7 +102,8 @@ export class IndexedDbProvider extends DbProvider {
explicitDbFactorySupportsCompoundKeys?: boolean,
handleOnClose?: OnCloseHandler,
logger?: IObjectStoreProviderLogger,
upgradeCallback?: UpgradeCallback
upgradeCallback?: UpgradeCallback,
private idbConfigs: IDBConfigs = defaultIDBConfigs
) {
super();

Expand Down Expand Up @@ -450,7 +460,8 @@ export class IndexedDbProvider extends DbProvider {
fakeToken,
schema,
this._fakeComplicatedKeys,
this.logWriter
this.logWriter,
this.idbConfigs
);
const tStore = iTrans.getStore(storeSchema.name);

Expand Down Expand Up @@ -688,7 +699,8 @@ export class IndexedDbProvider extends DbProvider {
transToken,
this._schema!!!,
this._fakeComplicatedKeys,
this.logWriter
this.logWriter,
this.idbConfigs
)
);
}
Expand All @@ -706,7 +718,8 @@ class IndexedDbTransaction implements DbTransaction {
private _transToken: TransactionToken,
private _schema: DbSchema,
private _fakeComplicatedKeys: boolean,
private logWriter: LogWriter
private logWriter: LogWriter,
private idbConfigs?: IDBConfigs
) {
this._stores = map(this._transToken.storeNames, (storeName) =>
this._trans.objectStore(storeName)
Expand Down Expand Up @@ -801,7 +814,8 @@ class IndexedDbTransaction implements DbTransaction {
store,
indexStores,
storeSchema,
this._fakeComplicatedKeys
this._fakeComplicatedKeys,
this.idbConfigs
);
}

Expand Down Expand Up @@ -839,7 +853,8 @@ class IndexedDbStore implements DbStore {
private _store: IDBObjectStore,
private _indexStores: IDBObjectStore[],
private _schema: StoreSchema,
private _fakeComplicatedKeys: boolean
private _fakeComplicatedKeys: boolean,
private idbConfigs?: IDBConfigs
) {
// NOP
}
Expand Down Expand Up @@ -1166,7 +1181,8 @@ class IndexedDbStore implements DbStore {
indexSchema,
this._schema.primaryKeyPath,
this._fakeComplicatedKeys,
this._store
this._store,
this.idbConfigs
);
} else {
const index = this._store.index(indexName);
Expand All @@ -1177,7 +1193,9 @@ class IndexedDbStore implements DbStore {
index,
indexSchema,
this._schema.primaryKeyPath,
this._fakeComplicatedKeys
this._fakeComplicatedKeys,
undefined,
this.idbConfigs
);
}
}
Expand All @@ -1187,7 +1205,9 @@ class IndexedDbStore implements DbStore {
this._store,
undefined,
this._schema.primaryKeyPath,
this._fakeComplicatedKeys
this._fakeComplicatedKeys,
undefined,
this.idbConfigs
);
}

Expand All @@ -1214,7 +1234,8 @@ class IndexedDbIndex extends DbIndexFTSFromRangeQueries {
indexSchema: IndexSchema | undefined,
primaryKeyPath: KeyPathType,
private _fakeComplicatedKeys: boolean,
private _fakedOriginalStore?: IDBObjectStore
private _fakedOriginalStore?: IDBObjectStore,
private idbConfigs?: IDBConfigs
) {
super(indexSchema, primaryKeyPath);
}
Expand Down Expand Up @@ -1351,6 +1372,29 @@ class IndexedDbIndex extends DbIndexFTSFromRangeQueries {
) {
return IndexedDbProvider.WrapRequest(this._store.getAll(keyRange, limit));
}

const shouldUseGetAllRecords = this.idbConfigs?.useGetAllRecordsForGetRange;
if (
shouldUseGetAllRecords &&
!!this._store.getAllRecords &&
typeof this._store.getAllRecords === "function" &&
reverse &&
!!limit &&
!offset
) {
// use getAllRecords for reverse order, if available.
// It does not support offset currently.
const query_options = {
direction: "prev",
count: limit,
query: keyRange,
} as IDBGetAllRecordsOptions;

return IndexedDbProvider.WrapRequest(
this._store.getAllRecords(query_options)
);
}

const req = this._store.openCursor(keyRange, reverse ? "prev" : "next");
return this._resolveCursorResult(req, limit, offset);
}
Expand Down
43 changes: 43 additions & 0 deletions src/types/extended-idb.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export {};

export type IDBGetAllRecordsOptions = {
// The maximum number of records to retrieve.
count: number;

// The direction of the cursor when retrieving records.
// "next" for ascending order, "prev" for descending order.
direction: "next" | "prev";

query: IDBKeyRange | null;
};

// Response of new getAllRecords method.
type IDBRecord = {
key: any;
primaryKey: any;
value: any;
};

// Extending interfaces with new methods, which are not in typeScript library yet.
// More details can be found in https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/IndexedDbGetAllEntries/explainer.md
declare global {
interface IDBIndex {
/**
* Retrieves all records in the index.
* This is an experimental new API and may not be available in all environments.
*/
getAllRecords?: (
options?: IDBGetAllRecordsOptions
) => IDBRequest<IDBRecord[]>;
}

interface IDBObjectStore {
/**
* Retrieves all records in the index
* This is an experimental new API and may not be available in all environments.
*/
getAllRecords?: (
options?: IDBGetAllRecordsOptions
) => IDBRequest<IDBRecord[]>;
}
}
Loading