Skip to content

Commit 091e573

Browse files
Merge master into release
2 parents 7272e7b + 1076551 commit 091e573

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1397
-633
lines changed

.changeset/calm-pugs-leave.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/app': patch
3+
---
4+
5+
Prevent core app from throwing if IndexedDB heartbeat functions throw.

.changeset/five-yaks-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/firestore': patch
3+
---
4+
5+
Add internal implementation of setIndexConfiguration

.changeset/honest-waves-brake.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/firestore': patch
3+
---
4+
5+
Expose client side indexing feature with `setIndexConfiguration`.

.changeset/kind-pots-admire.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@firebase/database': patch
3+
'@firebase/database-compat': patch
4+
'@firebase/database-types': patch
5+
---
6+
7+
Updated type of action parameter for DataSnapshot#forEach

.github/workflows/check-changeset.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: Check Changeset
22

3-
on: pull_request
3+
on:
4+
pull_request:
5+
branches-ignore:
6+
- release
47

58
env:
69
GITHUB_PULL_REQUEST_HEAD_SHA: ${{ github.event.pull_request.head.sha }}

.github/workflows/release-prod.yml

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
name: Production Release
22

3-
on: workflow_dispatch
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release-branch:
7+
description: 'Release branch'
8+
type: string
9+
default: 'release'
10+
required: true
411

512
jobs:
613
deploy:
@@ -20,7 +27,7 @@ jobs:
2027
with:
2128
# Release script requires git history and tags.
2229
fetch-depth: 0
23-
ref: release
30+
ref: ${{ github.event.inputs.release-branch }}
2431
token: ${{ secrets.OSS_BOT_GITHUB_TOKEN }}
2532
- name: Yarn install
2633
run: yarn

.github/workflows/test-changed.yml

+55-25
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,61 @@ name: Test Modified Packages
33
on: pull_request
44

55
jobs:
6-
test:
7-
name: Test Packages With Changed Files
6+
test-chrome:
7+
name: Test Packages With Changed Files in Chrome and Node
88
runs-on: ubuntu-latest
99

1010
steps:
11-
- name: Checkout Repo
12-
uses: actions/checkout@master
13-
with:
14-
# This makes Actions fetch all Git history so run-changed script can diff properly.
15-
fetch-depth: 0
16-
- name: Set up Node (14)
17-
uses: actions/setup-node@v2
18-
with:
19-
node-version: 14.x
20-
- name: install Chrome stable
21-
run: |
22-
sudo apt-get update
23-
sudo apt-get install google-chrome-stable
24-
- name: Bump Node memory limit
25-
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
26-
- name: Test setup and yarn install
27-
run: |
28-
cp config/ci.config.json config/project.json
29-
yarn
30-
- name: build
31-
run: yarn build:changed core
32-
- name: Run tests on changed packages
33-
run: xvfb-run yarn test:changed core
11+
- name: Checkout Repo
12+
uses: actions/checkout@master
13+
with:
14+
# This makes Actions fetch all Git history so run-changed script can diff properly.
15+
fetch-depth: 0
16+
- name: Set up Node (14)
17+
uses: actions/setup-node@v2
18+
with:
19+
node-version: 14.x
20+
- name: install Chrome stable
21+
run: |
22+
sudo apt-get update
23+
sudo apt-get install google-chrome-stable
24+
- name: Bump Node memory limit
25+
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
26+
- name: Test setup and yarn install
27+
run: |
28+
cp config/ci.config.json config/project.json
29+
yarn
30+
- name: build
31+
run: yarn build:changed core
32+
- name: Run tests on changed packages
33+
run: xvfb-run yarn test:changed core
34+
35+
test-firefox:
36+
name: Test Packages With Changed Files in Firefox
37+
runs-on: ubuntu-latest
38+
39+
steps:
40+
- name: Checkout Repo
41+
uses: actions/checkout@master
42+
with:
43+
fetch-depth: 0
44+
- name: Set up Node (14)
45+
uses: actions/setup-node@v2
46+
with:
47+
node-version: 14.x
48+
- name: install Firefox stable
49+
run: |
50+
sudo apt-get update
51+
sudo apt-get install firefox
52+
- name: Bump Node memory limit
53+
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
54+
- name: Test setup and yarn install
55+
run: |
56+
cp config/ci.config.json config/project.json
57+
yarn
58+
- name: build
59+
run: yarn build:changed core
60+
- name: Run tests on changed packages
61+
run: xvfb-run yarn test:changed core
62+
env:
63+
BROWSERS: 'Firefox'

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,5 @@ tsdoc-metadata.json
9393

9494
# generated html docs
9595
docs-*/
96-
docs/
96+
docs/
97+
toc/

common/api-review/database.api.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ export class DataSnapshot {
3333
child(path: string): DataSnapshot;
3434
exists(): boolean;
3535
exportVal(): any;
36-
forEach(action: (child: DataSnapshot) => boolean | void): boolean;
36+
forEach(action: (child: DataSnapshot & {
37+
key: string;
38+
}) => boolean | void): boolean;
3739
hasChild(path: string): boolean;
3840
hasChildren(): boolean;
3941
get key(): string | null;

common/api-review/firestore.api.md

+30
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,30 @@ export function getFirestore(app?: FirebaseApp): Firestore;
233233
// @public
234234
export function increment(n: number): FieldValue;
235235

236+
// @public
237+
export interface Index {
238+
// (undocumented)
239+
[key: string]: unknown;
240+
readonly collectionGroup: string;
241+
readonly fields?: IndexField[];
242+
}
243+
244+
// @public
245+
export interface IndexConfiguration {
246+
// (undocumented)
247+
[key: string]: unknown;
248+
readonly indexes?: Index[];
249+
}
250+
251+
// @public
252+
export interface IndexField {
253+
// (undocumented)
254+
[key: string]: unknown;
255+
readonly arrayConfig?: 'CONTAINS';
256+
readonly fieldPath: string;
257+
readonly order?: 'ASCENDING' | 'DESCENDING';
258+
}
259+
236260
// @public
237261
export function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings): Firestore;
238262

@@ -396,6 +420,12 @@ export function setDoc<T>(reference: DocumentReference<T>, data: WithFieldValue<
396420
// @public
397421
export function setDoc<T>(reference: DocumentReference<T>, data: PartialWithFieldValue<T>, options: SetOptions): Promise<void>;
398422

423+
// @public
424+
export function setIndexConfiguration(firestore: Firestore, configuration: IndexConfiguration): Promise<void>;
425+
426+
// @public
427+
export function setIndexConfiguration(firestore: Firestore, json: string): Promise<void>;
428+
399429
// @public
400430
export function setLogLevel(logLevel: LogLevel): void;
401431

config/karma.base.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const config = {
6060
// start these browsers
6161
// available browser launchers:
6262
// https://npmjs.org/browse/keyword/karma-launcher
63-
browsers: ['ChromeHeadless'],
63+
browsers: process.env?.BROWSERS?.split(',') ?? ['ChromeHeadless'],
6464

6565
webpack: webpackTestConfig,
6666

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
"sinon": "9.2.4",
147147
"sinon-chai": "3.7.0",
148148
"source-map-loader": "1.1.3",
149-
"terser": "5.13.1",
149+
"terser": "5.14.2",
150150
"ts-loader": "8.4.0",
151151
"ts-node": "10.7.0",
152152
"tslint": "6.1.3",

packages/app/src/errors.ts

+16-16
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ export const enum AppError {
2424
APP_DELETED = 'app-deleted',
2525
INVALID_APP_ARGUMENT = 'invalid-app-argument',
2626
INVALID_LOG_ARGUMENT = 'invalid-log-argument',
27-
STORAGE_OPEN = 'storage-open',
28-
STORAGE_GET = 'storage-get',
29-
STORAGE_WRITE = 'storage-set',
30-
STORAGE_DELETE = 'storage-delete'
27+
IDB_OPEN = 'idb-open',
28+
IDB_GET = 'idb-get',
29+
IDB_WRITE = 'idb-set',
30+
IDB_DELETE = 'idb-delete'
3131
}
3232

3333
const ERRORS: ErrorMap<AppError> = {
@@ -43,14 +43,14 @@ const ERRORS: ErrorMap<AppError> = {
4343
'Firebase App instance.',
4444
[AppError.INVALID_LOG_ARGUMENT]:
4545
'First argument to `onLog` must be null or a function.',
46-
[AppError.STORAGE_OPEN]:
47-
'Error thrown when opening storage. Original error: {$originalErrorMessage}.',
48-
[AppError.STORAGE_GET]:
49-
'Error thrown when reading from storage. Original error: {$originalErrorMessage}.',
50-
[AppError.STORAGE_WRITE]:
51-
'Error thrown when writing to storage. Original error: {$originalErrorMessage}.',
52-
[AppError.STORAGE_DELETE]:
53-
'Error thrown when deleting from storage. Original error: {$originalErrorMessage}.'
46+
[AppError.IDB_OPEN]:
47+
'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',
48+
[AppError.IDB_GET]:
49+
'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',
50+
[AppError.IDB_WRITE]:
51+
'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',
52+
[AppError.IDB_DELETE]:
53+
'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'
5454
};
5555

5656
interface ErrorParams {
@@ -59,10 +59,10 @@ interface ErrorParams {
5959
[AppError.DUPLICATE_APP]: { appName: string };
6060
[AppError.APP_DELETED]: { appName: string };
6161
[AppError.INVALID_APP_ARGUMENT]: { appName: string };
62-
[AppError.STORAGE_OPEN]: { originalErrorMessage?: string };
63-
[AppError.STORAGE_GET]: { originalErrorMessage?: string };
64-
[AppError.STORAGE_WRITE]: { originalErrorMessage?: string };
65-
[AppError.STORAGE_DELETE]: { originalErrorMessage?: string };
62+
[AppError.IDB_OPEN]: { originalErrorMessage?: string };
63+
[AppError.IDB_GET]: { originalErrorMessage?: string };
64+
[AppError.IDB_WRITE]: { originalErrorMessage?: string };
65+
[AppError.IDB_DELETE]: { originalErrorMessage?: string };
6666
}
6767

6868
export const ERROR_FACTORY = new ErrorFactory<AppError, ErrorParams>(

packages/app/src/indexeddb.test.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* @license
3+
* Copyright 2022 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
import '../test/setup';
20+
import { match, stub } from 'sinon';
21+
import {
22+
readHeartbeatsFromIndexedDB,
23+
writeHeartbeatsToIndexedDB
24+
} from './indexeddb';
25+
import { FirebaseApp } from './public-types';
26+
import { AppError } from './errors';
27+
import { HeartbeatsInIndexedDB } from './types';
28+
29+
/**
30+
* Mostly testing failure cases. heartbeatService.test.ts tests read-write
31+
* more extensively.
32+
*/
33+
34+
describe('IndexedDB functions', () => {
35+
it('readHeartbeatsFromIndexedDB warns if IndexedDB.open() throws', async () => {
36+
const warnStub = stub(console, 'warn');
37+
if (typeof window !== 'undefined') {
38+
// Ensure that indexedDB.open() fails in browser. It will always fail in Node.
39+
stub(window.indexedDB, 'open').throws(new Error('abcd'));
40+
await readHeartbeatsFromIndexedDB({
41+
name: 'testname',
42+
options: { appId: 'test-app-id' }
43+
} as FirebaseApp);
44+
expect(warnStub).to.be.calledWith(match.any, match(AppError.IDB_GET));
45+
} else {
46+
await readHeartbeatsFromIndexedDB({
47+
name: 'testname',
48+
options: { appId: 'test-app-id' }
49+
} as FirebaseApp);
50+
expect(warnStub).to.be.calledWith(match.any, match(AppError.IDB_GET));
51+
}
52+
});
53+
it('writeHeartbeatsToIndexedDB warns if IndexedDB.open() throws', async () => {
54+
const warnStub = stub(console, 'warn');
55+
if (typeof window !== 'undefined') {
56+
// Ensure that indexedDB.open() fails in browser. It will always fail in Node.
57+
stub(window.indexedDB, 'open').throws(new Error('abcd'));
58+
await writeHeartbeatsToIndexedDB(
59+
{
60+
name: 'testname',
61+
options: { appId: 'test-app-id' }
62+
} as FirebaseApp,
63+
{} as HeartbeatsInIndexedDB
64+
);
65+
expect(warnStub).to.be.calledWith(match.any, match(AppError.IDB_WRITE));
66+
} else {
67+
await writeHeartbeatsToIndexedDB(
68+
{
69+
name: 'testname',
70+
options: { appId: 'test-app-id' }
71+
} as FirebaseApp,
72+
{} as HeartbeatsInIndexedDB
73+
);
74+
expect(warnStub).to.be.calledWith(match.any, match(AppError.IDB_WRITE));
75+
}
76+
});
77+
});

0 commit comments

Comments
 (0)