Skip to content

Commit 819f979

Browse files
authored
Use a cross-process lock to signal port destruction. (#34)
We used an `unload` listener for this before, but this event is both deprecated and unreliable. Instead, switch to using an exclusive lock that the parent process acquires first and releases only when the tab is destroyed. The worker tries to acquire the same lock on port init and assumes the process on the other side of the port has been destroyed once the lock is successfully acquired.
1 parent aab27cd commit 819f979

9 files changed

Lines changed: 29 additions & 20 deletions

dist/firetruss.es2015.js

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/firetruss.es2015.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/firetruss.umd.js

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/firetruss.umd.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/firetruss.umd.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/firetruss.umd.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "firetruss",
3-
"version": "7.6.5",
3+
"version": "7.7.0",
44
"description": "Advanced data sync layer for Firebase and Vue.js",
55
"scripts": {
66
"update": "yarn upgrade-interactive --latest",

src/Bridge.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {unescapeKey} from './utils/paths.js';
22
import _ from 'lodash';
33

4-
const MIN_WORKER_VERSION = '3.0.0';
4+
const MIN_WORKER_VERSION = '4.0.0';
55

66

77
class Snapshot {
@@ -51,10 +51,9 @@ export default class Bridge {
5151
this._shared = !!webWorker.port;
5252
Object.seal(this);
5353
this._port.onmessage = this._receive.bind(this);
54-
window.addEventListener('unload', () => {this._send({msg: 'destroy'});});
5554
}
5655

57-
init(webWorker, config) {
56+
init(lockName, config) {
5857
const items = [];
5958
try {
6059
const storage = window.localStorage || window.sessionStorage;
@@ -66,7 +65,7 @@ export default class Bridge {
6665
} catch {
6766
// Some browsers don't like us accessing local storage -- nothing we can do.
6867
}
69-
return this._send({msg: 'init', storage: items, config}).then(response => {
68+
return this._send({msg: 'init', storage: items, config, lockName}).then(response => {
7069
const workerVersion = response.version.match(/^(\d+)\.(\d+)\.(\d+)(-.*)?$/);
7170
if (workerVersion) {
7271
const minVersion = MIN_WORKER_VERSION.match(/^(\d+)\.(\d+)\.(\d+)(-.*)?$/);

src/Truss.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,15 @@ export default class Truss {
241241
if (_.isString(webWorker)) {
242242
const Worker = window.SharedWorker || window.Worker;
243243
if (!Worker) throw new Error('Browser does not implement Web Workers');
244+
if (!navigator.locks) throw new Error('Browser does not implement locks');
244245
webWorker = new Worker(webWorker);
246+
const random = window.crypto.getRandomValues(new Uint32Array(1))[0];
247+
webWorker.lockName = `truss_worker_lock_${Date.now()}.${random}`;
248+
navigator.locks.request(webWorker.lockName, () => new Promise(_.noop));
245249
}
246250
bridge = new Bridge(webWorker);
247251
if (logging) bridge.enableLogging(logging);
248-
return bridge.init(webWorker, config).then(
252+
return bridge.init(webWorker.lockName, config).then(
249253
({exposedFunctionNames, firebaseSdkVersion}) => {
250254
Object.defineProperty(Truss, 'FIREBASE_SDK_VERSION', {value: firebaseSdkVersion});
251255
for (const name of exposedFunctionNames) Truss.preExpose(name);

0 commit comments

Comments
 (0)