Skip to content

Commit fba771f

Browse files
committed
register rc exp
1 parent 6e0b16f commit fba771f

File tree

4 files changed

+52
-186
lines changed

4 files changed

+52
-186
lines changed

packages-exp/remote-config-exp/index.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,9 @@
1616
*/
1717

1818
import firebase from '@firebase/app';
19-
import '@firebase/installations';
19+
import '@firebase/installations-exp';
2020
import { _FirebaseNamespace } from '@firebase/app-types/private';
2121
import { RemoteConfig as RemoteConfigType } from '@firebase/remote-config-types';
22-
import { CachingClient } from './src/client/caching_client';
23-
import { RestClient } from './src/client/rest_client';
24-
import { RemoteConfig } from './src/remote_config';
25-
import { Storage } from './src/storage/storage';
26-
import { StorageCache } from './src/storage/storage_cache';
27-
import { ERROR_FACTORY, ErrorCode } from './src/errors';
28-
import { RetryingClient } from './src/client/retrying_client';
29-
import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger';
30-
import { name as packageName, version } from './package.json';
31-
import {
32-
Component,
33-
ComponentType,
34-
ComponentContainer
35-
} from '@firebase/component';
3622

3723
// Facilitates debugging by enabling settings changes without rebuilding asset.
3824
// Note these debug options are not part of a documented, supported API and can change at any time.

packages-exp/remote-config-exp/src/client/rest_client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { FirebaseInstallations } from '@firebase/installations-types';
1918
import {
2019
FetchResponse,
2120
RemoteConfigFetchClient,
@@ -24,6 +23,7 @@ import {
2423
} from './remote_config_fetch_client';
2524
import { ERROR_FACTORY, ErrorCode } from '../errors';
2625
import { getUserLanguage } from '../language';
26+
import { _FirebaseInstallationsInternal } from '@firebase/installations-types-exp';
2727

2828
/**
2929
* Defines request body parameters required to call the fetch API:
@@ -49,7 +49,7 @@ interface FetchRequestBody {
4949
*/
5050
export class RestClient implements RemoteConfigFetchClient {
5151
constructor(
52-
private readonly firebaseInstallations: FirebaseInstallations,
52+
private readonly firebaseInstallations: _FirebaseInstallationsInternal,
5353
private readonly sdkVersion: string,
5454
private readonly namespace: string,
5555
private readonly projectId: string,

packages-exp/remote-config-exp/src/register.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,52 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
import {
18+
_registerComponent,
19+
registerVersion,
20+
SDK_VERSION
21+
} from '@firebase/app-exp';
22+
import {
23+
Component,
24+
ComponentType,
25+
ComponentContainer
26+
} from '@firebase/component';
27+
import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger';
28+
import { RemoteConfig } from '@firebase/remote-config-types-exp';
29+
import { name as packageName, version } from '../package.json';
30+
import { ensureInitialized } from './api';
31+
import { CachingClient } from './client/caching_client';
32+
import { RestClient } from './client/rest_client';
33+
import { RetryingClient } from './client/retrying_client';
34+
import { ErrorCode, ERROR_FACTORY } from './errors';
35+
import { RemoteConfig as RemoteConfigImpl } from './remote_config';
36+
import { Storage } from './storage/storage';
37+
import { StorageCache } from './storage/storage_cache';
1738

18-
export function registerRemoteConfig(
19-
firebaseInstance: _FirebaseNamespace
20-
): void {
21-
firebaseInstance.INTERNAL.registerComponent(
39+
const RC_COMPONENT_NAME = 'remote-config-exp';
40+
41+
export function registerRemoteConfig(): void {
42+
_registerComponent(
2243
new Component(
23-
'remoteConfig',
44+
RC_COMPONENT_NAME,
2445
remoteConfigFactory,
2546
ComponentType.PUBLIC
2647
).setMultipleInstances(true)
2748
);
2849

29-
firebaseInstance.registerVersion(packageName, version);
50+
registerVersion(packageName, version);
3051

3152
function remoteConfigFactory(
3253
container: ComponentContainer,
3354
namespace?: string
3455
): RemoteConfig {
3556
/* Dependencies */
3657
// getImmediate for FirebaseApp will always succeed
37-
const app = container.getProvider('app').getImmediate();
58+
const app = container.getProvider('app-exp').getImmediate();
3859
// The following call will always succeed because rc has `import '@firebase/installations'`
39-
const installations = container.getProvider('installations').getImmediate();
60+
const installations = container
61+
.getProvider('installations-exp-internal')
62+
.getImmediate();
4063

4164
// Guards against the SDK being used in non-browser environments.
4265
if (typeof window === 'undefined') {
@@ -68,7 +91,7 @@ export function registerRemoteConfig(
6891
const restClient = new RestClient(
6992
installations,
7093
// Uses the JS SDK version, by which the RC package version can be deduced, if necessary.
71-
firebaseInstance.SDK_VERSION,
94+
SDK_VERSION,
7295
namespace,
7396
projectId,
7497
apiKey,
@@ -82,7 +105,7 @@ export function registerRemoteConfig(
82105
logger
83106
);
84107

85-
const remoteConfigInstance = new RemoteConfig(
108+
const remoteConfigInstance = new RemoteConfigImpl(
86109
app,
87110
cachingClient,
88111
storageCache,
@@ -92,7 +115,7 @@ export function registerRemoteConfig(
92115

93116
// Starts warming cache.
94117
// eslint-disable-next-line @typescript-eslint/no-floating-promises
95-
remoteConfigInstance.ensureInitialized();
118+
ensureInitialized(remoteConfigInstance);
96119

97120
return remoteConfigInstance;
98121
}

packages-exp/remote-config-exp/src/remote_config.ts

Lines changed: 15 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,16 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { FirebaseApp } from '@firebase/app-types';
18+
import { FirebaseApp } from '@firebase/app-types-exp';
1919
import {
2020
RemoteConfig as RemoteConfigType,
2121
FetchStatus,
22-
Settings,
23-
Value as ValueType,
24-
LogLevel as RemoteConfigLogLevel
25-
} from '@firebase/remote-config-types';
22+
Settings
23+
} from '@firebase/remote-config-types-exp';
2624
import { StorageCache } from './storage/storage_cache';
27-
import {
28-
RemoteConfigFetchClient,
29-
RemoteConfigAbortSignal
30-
} from './client/remote_config_fetch_client';
31-
import { Value } from './value';
32-
import { ErrorCode, hasErrorCode } from './errors';
25+
import { RemoteConfigFetchClient } from './client/remote_config_fetch_client';
3326
import { Storage } from './storage/storage';
34-
import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger';
27+
import { Logger } from '@firebase/logger';
3528

3629
const DEFAULT_FETCH_TIMEOUT_MILLIS = 60 * 1000; // One minute
3730
const DEFAULT_CACHE_MAX_AGE_MILLIS = 12 * 60 * 60 * 1000; // Twelve hours.
@@ -42,11 +35,17 @@ const DEFAULT_CACHE_MAX_AGE_MILLIS = 12 * 60 * 60 * 1000; // Twelve hours.
4235
* See {@link https://github.com/FirebasePrivate/firebase-js-sdk/blob/master/packages/firebase/index.d.ts|interface documentation} for method descriptions.
4336
*/
4437
export class RemoteConfig implements RemoteConfigType {
45-
// Tracks completion of initialization promise.
46-
private _isInitializationComplete = false;
38+
/**
39+
* Tracks completion of initialization promise.
40+
* @internal
41+
*/
42+
public _isInitializationComplete = false;
4743

48-
// De-duplicates initialization calls.
49-
private _initializePromise?: Promise<void>;
44+
/**
45+
* De-duplicates initialization calls.
46+
* @internal
47+
*/
48+
public _initializePromise?: Promise<void>;
5049

5150
settings: Settings = {
5251
fetchTimeoutMillis: DEFAULT_FETCH_TIMEOUT_MILLIS,
@@ -55,21 +54,6 @@ export class RemoteConfig implements RemoteConfigType {
5554

5655
defaultConfig: { [key: string]: string | number | boolean } = {};
5756

58-
// Based on packages/firestore/src/util/log.ts but not static because we need per-instance levels
59-
// to differentiate 2p and 3p use-cases.
60-
setLogLevel(logLevel: RemoteConfigLogLevel): void {
61-
switch (logLevel) {
62-
case 'debug':
63-
this._logger.logLevel = FirebaseLogLevel.DEBUG;
64-
break;
65-
case 'silent':
66-
this._logger.logLevel = FirebaseLogLevel.SILENT;
67-
break;
68-
default:
69-
this._logger.logLevel = FirebaseLogLevel.ERROR;
70-
}
71-
}
72-
7357
get fetchTimeMillis(): number {
7458
return this._storageCache.getLastSuccessfulFetchTimestampMillis() || -1;
7559
}
@@ -89,131 +73,4 @@ export class RemoteConfig implements RemoteConfigType {
8973
private readonly _storage: Storage,
9074
private readonly _logger: Logger
9175
) {}
92-
93-
async activate(): Promise<boolean> {
94-
const [lastSuccessfulFetchResponse, activeConfigEtag] = await Promise.all([
95-
this._storage.getLastSuccessfulFetchResponse(),
96-
this._storage.getActiveConfigEtag()
97-
]);
98-
if (
99-
!lastSuccessfulFetchResponse ||
100-
!lastSuccessfulFetchResponse.config ||
101-
!lastSuccessfulFetchResponse.eTag ||
102-
lastSuccessfulFetchResponse.eTag === activeConfigEtag
103-
) {
104-
// Either there is no successful fetched config, or is the same as current active
105-
// config.
106-
return false;
107-
}
108-
await Promise.all([
109-
this._storageCache.setActiveConfig(lastSuccessfulFetchResponse.config),
110-
this._storage.setActiveConfigEtag(lastSuccessfulFetchResponse.eTag)
111-
]);
112-
return true;
113-
}
114-
115-
ensureInitialized(): Promise<void> {
116-
if (!this._initializePromise) {
117-
this._initializePromise = this._storageCache
118-
.loadFromStorage()
119-
.then(() => {
120-
this._isInitializationComplete = true;
121-
});
122-
}
123-
return this._initializePromise;
124-
}
125-
126-
/**
127-
* @throws a {@link ErrorCode.FETCH_CLIENT_TIMEOUT} if the request takes longer than
128-
* {@link Settings.fetchTimeoutInSeconds} or
129-
* {@link DEFAULT_FETCH_TIMEOUT_SECONDS}.
130-
*/
131-
async fetch(): Promise<void> {
132-
// Aborts the request after the given timeout, causing the fetch call to
133-
// reject with an AbortError.
134-
//
135-
// <p>Aborting after the request completes is a no-op, so we don't need a
136-
// corresponding clearTimeout.
137-
//
138-
// Locating abort logic here because:
139-
// * it uses a developer setting (timeout)
140-
// * it applies to all retries (like curl's max-time arg)
141-
// * it is consistent with the Fetch API's signal input
142-
const abortSignal = new RemoteConfigAbortSignal();
143-
144-
setTimeout(async () => {
145-
// Note a very low delay, eg < 10ms, can elapse before listeners are initialized.
146-
abortSignal.abort();
147-
}, this.settings.fetchTimeoutMillis);
148-
149-
// Catches *all* errors thrown by client so status can be set consistently.
150-
try {
151-
await this._client.fetch({
152-
cacheMaxAgeMillis: this.settings.minimumFetchIntervalMillis,
153-
signal: abortSignal
154-
});
155-
156-
await this._storageCache.setLastFetchStatus('success');
157-
} catch (e) {
158-
const lastFetchStatus = hasErrorCode(e, ErrorCode.FETCH_THROTTLE)
159-
? 'throttle'
160-
: 'failure';
161-
await this._storageCache.setLastFetchStatus(lastFetchStatus);
162-
throw e;
163-
}
164-
}
165-
166-
async fetchAndActivate(): Promise<boolean> {
167-
await this.fetch();
168-
return this.activate();
169-
}
170-
171-
getAll(): { [key: string]: ValueType } {
172-
return getAllKeys(
173-
this._storageCache.getActiveConfig(),
174-
this.defaultConfig
175-
).reduce((allConfigs, key) => {
176-
allConfigs[key] = this.getValue(key);
177-
return allConfigs;
178-
}, {} as { [key: string]: ValueType });
179-
}
180-
181-
getBoolean(key: string): boolean {
182-
return this.getValue(key).asBoolean();
183-
}
184-
185-
getNumber(key: string): number {
186-
return this.getValue(key).asNumber();
187-
}
188-
189-
getString(key: string): string {
190-
return this.getValue(key).asString();
191-
}
192-
193-
getValue(key: string): ValueType {
194-
if (!this._isInitializationComplete) {
195-
this._logger.debug(
196-
`A value was requested for key "${key}" before SDK initialization completed.` +
197-
' Await on ensureInitialized if the intent was to get a previously activated value.'
198-
);
199-
}
200-
const activeConfig = this._storageCache.getActiveConfig();
201-
if (activeConfig && activeConfig[key] !== undefined) {
202-
return new Value('remote', activeConfig[key]);
203-
} else if (this.defaultConfig && this.defaultConfig[key] !== undefined) {
204-
return new Value('default', String(this.defaultConfig[key]));
205-
}
206-
this._logger.debug(
207-
`Returning static value for key "${key}".` +
208-
' Define a default or remote value if this is unintentional.'
209-
);
210-
return new Value('static');
211-
}
212-
}
213-
214-
/**
215-
* Dedupes and returns an array of all the keys of the received objects.
216-
*/
217-
function getAllKeys(obj1: {} = {}, obj2: {} = {}): string[] {
218-
return Object.keys({ ...obj1, ...obj2 });
21976
}

0 commit comments

Comments
 (0)