Skip to content

Add Firestore, initializeFirestore, getFirestore to Firestore lite #3108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 29, 2020
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
24 changes: 24 additions & 0 deletions packages/firestore/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module.exports = {
extends: '../../config/.eslintrc.js',
parserOptions: {
Expand Down Expand Up @@ -35,6 +52,13 @@ module.exports = {
rules: {
'@typescript-eslint/no-explicit-any': 'error'
}
},
// TODO(firestorelite): Remove this exception when app-exp is published
{
files: ['lite/**/*.ts'],
rules: {
'import/no-extraneous-dependencies': 'off'
}
}
]
};
2 changes: 1 addition & 1 deletion packages/firestore/lite/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import { FirebaseApp } from '@firebase/app-types';
import { FirebaseApp } from '@firebase/app-types-exp';

/* eslint-disable @typescript-eslint/no-explicit-any */

Expand Down
46 changes: 46 additions & 0 deletions packages/firestore/lite/index.node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { registerVersion, _registerComponent } from '@firebase/app-exp';
import { Firestore } from './src/api/database';
import { version } from '../package.json';
import { Component, ComponentType } from '@firebase/component';

export {
Firestore,
initializeFirestore,
getFirestore
} from './src/api/database';

export function registerFirestore(): void {
_registerComponent(
new Component(
'firestore/lite',
container => {
const app = container.getProvider('app-exp').getImmediate()!;
return ((app, auth) => new Firestore(app, auth))(
app,
container.getProvider('auth-internal')
);
},
ComponentType.PUBLIC
)
);
registerVersion('firestore-lite', version, 'node');
}

registerFirestore();
6 changes: 6 additions & 0 deletions packages/firestore/lite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@firebase/firestore/lite",
"description": "A lite version of the Firestore SDK",
"main": "../dist/lite/index.node.cjs.js",
"private": true
}
100 changes: 100 additions & 0 deletions packages/firestore/lite/src/api/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as firestore from '../../';

import { _getProvider } from '@firebase/app-exp';
import { FirebaseApp } from '@firebase/app-types-exp';
import { Provider } from '@firebase/component';

import { Code, FirestoreError } from '../../../src/util/error';
import { DatabaseId } from '../../../src/core/database_info';
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import {
CredentialsProvider,
FirebaseCredentialsProvider
} from '../../../src/api/credentials';

// TODO(firestorelite): Depend on FirebaseService once #3112 is merged

/**
* The root reference to the Firestore Lite database.
*/
export class Firestore implements firestore.FirebaseFirestore {
readonly _databaseId: DatabaseId;
private readonly _firebaseApp: FirebaseApp;
private readonly _credentials: CredentialsProvider;
private _settings?: firestore.Settings;

constructor(
app: FirebaseApp,
authProvider: Provider<FirebaseAuthInternalName>
) {
this._firebaseApp = app;
this._databaseId = Firestore.databaseIdFromApp(app);
this._credentials = new FirebaseCredentialsProvider(authProvider);
}

get app(): FirebaseApp {
return this._firebaseApp;
}

_configureClient(settings: firestore.Settings): void {
if (this._settings) {
throw new FirestoreError(
Code.FAILED_PRECONDITION,
'Firestore has already been started and its settings can no longer ' +
'be changed. initializeFirestore() cannot be called after calling ' +
'getFirestore().'
);
}
this._settings = settings;
}

_ensureClientConfigured(): void {
if (!this._settings) {
this._settings = {};
}
}

private static databaseIdFromApp(app: FirebaseApp): DatabaseId {
if (!Object.prototype.hasOwnProperty.apply(app.options, ['projectId'])) {
throw new FirestoreError(
Code.INVALID_ARGUMENT,
'"projectId" not provided in firebase.initializeApp.'
);
}

return new DatabaseId(app.options.projectId!);
}
}

export function initializeFirestore(
app: FirebaseApp,
settings: firestore.Settings
): Firestore {
const firestore = _getProvider(
app,
'firestore/lite'
).getImmediate() as Firestore;
firestore._configureClient(settings);
return firestore;
}

export function getFirestore(app: FirebaseApp): Firestore {
return _getProvider(app, 'firestore/lite').getImmediate() as Firestore;
}
59 changes: 59 additions & 0 deletions packages/firestore/lite/test/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { expect } from 'chai';

import { initializeApp } from '@firebase/app-exp';
import {
Firestore,
getFirestore,
initializeFirestore
} from '../src/api/database';

describe('Firestore', () => {
it('can provide setting', () => {
const app = initializeApp(
{ apiKey: 'fake-api-key', projectId: 'test-project' },
'test-app-initializeFirestore'
);
const fs1 = initializeFirestore(app, { host: 'localhost', ssl: false });
expect(fs1).to.be.an.instanceOf(Firestore);
});

it('returns same instance', () => {
const app = initializeApp(
{ apiKey: 'fake-api-key', projectId: 'test-project' },
'test-app-getFirestore'
);
const fs1 = getFirestore(app);
const fs2 = getFirestore(app);
expect(fs1 === fs2).to.be.true;
});

it('cannot call initializeFirestore() twice', () => {
const app = initializeApp(
{ apiKey: 'fake-api-key', projectId: 'test-project' },
'test-app-initializeFirestore-twice'
);
initializeFirestore(app, { host: 'localhost', ssl: false });
expect(() => {
initializeFirestore(app, { host: 'localhost', ssl: false });
}).to.throw(
'Firestore has already been started and its settings can no longer be changed.'
);
});
});
7 changes: 6 additions & 1 deletion packages/firestore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
"scripts": {
"prebuild": "tsc -m es2015 --moduleResolution node scripts/*.ts ",
"build": "rollup -c rollup.config.es2017.js && rollup -c rollup.config.es5.js",
"build": "rollup -c rollup.config.es2017.js && rollup -c rollup.config.es5.js && yarn build:lite",
"build:deps": "lerna run --scope @firebase/'{app,firestore}' --include-dependencies build",
"build:console": "node tools/console.build.js",
"build:exp": "rollup -c rollup.config.exp.js",
"build:lite": "rollup -c rollup.config.lite.js",
"predev": "yarn prebuild",
"dev": "rollup -c -w",
"lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
Expand All @@ -32,6 +33,8 @@
"test:node:persistence:prod": "USE_MOCK_PERSISTENCE=YES TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --require ts-node/register --require index.node.ts --require test/util/node_persistence.ts --config ../../config/mocharc.node.js",
"test:travis": "ts-node --compiler-options='{\"module\":\"commonjs\"}' ../../scripts/emulator-testing/firestore-test-runner.ts",
"test:minified": "(cd ../../integration/firestore ; yarn test)",
"pretest:lite": "yarn build:lite",
"test:lite": "TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'lite/test/**/*.test.ts' --file lite/index.node.ts --config ../../config/mocharc.node.js",
"prepare": "yarn build"
},
"main": "dist/index.node.cjs.js",
Expand Down Expand Up @@ -60,6 +63,8 @@
"@firebase/app-types": "0.x"
},
"devDependencies": {
"@firebase/app-exp": "0.x",
"@firebase/app-types-exp": "0.x",
"@types/json-stable-stringify": "1.0.32",
"json-stable-stringify": "1.0.1",
"protobufjs": "6.9.0",
Expand Down
57 changes: 57 additions & 0 deletions packages/firestore/rollup.config.lite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import json from 'rollup-plugin-json';
import typescriptPlugin from 'rollup-plugin-typescript2';
import typescript from 'typescript';

import { resolveNodeExterns } from './rollup.shared';

import pkg from './lite/package.json';
import path from 'path';

const defaultPlugins = [
typescriptPlugin({
typescript,
tsconfigOverride: {
compilerOptions: {
target: 'es2017'
}
},
clean: true
}),
json({ preferConst: true })
];

const nodeBuilds = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you will add browser builds eventually?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This slows down development for now. Added TODO.

{
input: 'lite/index.node.ts',
output: {
file: path.resolve('./lite', pkg.main),
format: 'es'
},
plugins: defaultPlugins,
external: resolveNodeExterns,
treeshake: {
tryCatchDeoptimization: false
}
}
];

// TODO(firestorelite): Add browser builds

export default [...nodeBuilds];