diff --git a/.changeset/good-bears-obey.md b/.changeset/good-bears-obey.md new file mode 100644 index 00000000000..e3295293d58 --- /dev/null +++ b/.changeset/good-bears-obey.md @@ -0,0 +1,5 @@ +--- +"@firebase/database": patch +--- + +Included experimental support for Deno diff --git a/packages/database/src/core/util/util.ts b/packages/database/src/core/util/util.ts index 4ce187b755c..09c37bafe24 100644 --- a/packages/database/src/core/util/util.ts +++ b/packages/database/src/core/util/util.ts @@ -618,10 +618,21 @@ export const setTimeoutNonBlocking = function ( time: number ): number | object { const timeout: number | object = setTimeout(fn, time); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (typeof timeout === 'object' && (timeout as any)['unref']) { + // Note: at the time of this comment, unrefTimer is under the unstable set of APIs. Run with --unstable to enable the API. + if ( + typeof timeout === 'number' && + // @ts-ignore Is only defined in Deno environments. + typeof Deno !== 'undefined' && + // @ts-ignore Deno and unrefTimer are only defined in Deno environments. + Deno['unrefTimer'] + ) { + // @ts-ignore Deno and unrefTimer are only defined in Deno environments. + Deno.unrefTimer(timeout); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } else if (typeof timeout === 'object' && (timeout as any)['unref']) { // eslint-disable-next-line @typescript-eslint/no-explicit-any (timeout as any)['unref'](); } + return timeout; }; diff --git a/packages/database/test/deno.test.ts b/packages/database/test/deno.test.ts new file mode 100644 index 00000000000..5a88f74feff --- /dev/null +++ b/packages/database/test/deno.test.ts @@ -0,0 +1,52 @@ +/** + * @license + * Copyright 2022 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, use } from 'chai'; +import * as sinon from 'sinon'; +import sinonChai from 'sinon-chai'; + +import { setTimeoutNonBlocking } from '../src/core/util/util'; +use(sinonChai); +describe('Deno tests', () => { + let oldSetTimeout; + beforeEach(() => { + oldSetTimeout = globalThis.setTimeout; + }); + afterEach(() => { + globalThis.setTimeout = oldSetTimeout; + }); + it('should call the deno unrefTimer() if in Deno', () => { + // @ts-ignore override nodejs behavior + global.Deno = { + unrefTimer: sinon.spy() + }; + // @ts-ignore override nodejs behavior + global.setTimeout = () => 1; + setTimeoutNonBlocking(() => {}, 0); + expect(globalThis.Deno.unrefTimer).to.have.been.called; + }); + it('should not call the deno unrefTimer() if not in Deno', () => { + // @ts-ignore override nodejs behavior + global.Deno2 = { + unrefTimer: sinon.spy() + }; + // @ts-ignore override node.js behavior + global.setTimeout = () => 1; + setTimeoutNonBlocking(() => {}, 0); + expect(globalThis.Deno2.unrefTimer).to.not.have.been.called; + }); +}); diff --git a/scripts/emulator-testing/emulators/database-emulator.ts b/scripts/emulator-testing/emulators/database-emulator.ts index 7c9576c4b4c..86079e379e6 100644 --- a/scripts/emulator-testing/emulators/database-emulator.ts +++ b/scripts/emulator-testing/emulators/database-emulator.ts @@ -19,7 +19,7 @@ import * as request from 'request'; import { Emulator } from './emulator'; -import * as rulesJSON from '../../../config/database.rules.json'; +import rulesJSON from '../../../config/database.rules.json'; export class DatabaseEmulator extends Emulator { namespace: string;