Skip to content
Open
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
167 changes: 5 additions & 162 deletions dist/firetruss.es2015.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/firetruss.es2015.js.map

Large diffs are not rendered by default.

167 changes: 5 additions & 162 deletions dist/firetruss.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/firetruss.umd.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/firetruss.umd.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/firetruss.umd.min.js.map

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "firetruss",
"version": "7.9.0",
"version": "8.0.0",
"description": "Advanced data sync layer for Firebase and Vue.js",
"scripts": {
"update": "yarn up -R '*' && yarn dedupe --strategy highest",
Expand All @@ -16,8 +16,7 @@
"firebase",
"vuejs",
"model",
"worker",
"angular"
"worker"
],
"author": "Piotr Kaminski",
"license": "MIT",
Expand Down
25 changes: 1 addition & 24 deletions src/Connector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {Handle, Query, Reference} from './Reference.js';
import angular from './angularCompatibility.js';
import stats from './utils/stats.js';
import {isTrussEqual} from './utils/utils.js';

Expand All @@ -17,7 +16,6 @@ export default class Connector {

this._subConnectors = {};
this._disconnects = {};
this._angularUnwatches = undefined;
this._data = {};
this._vue = new Vue({data: {
descriptors: {},
Expand All @@ -37,10 +35,6 @@ export default class Connector {
this._connect(key, descriptor);
}
});

if (angular.active && scope && scope.$on && scope.$id) {
scope.$on('$destroy', () => {this.destroy();});
}
}

get ready() {
Expand All @@ -62,7 +56,6 @@ export default class Connector {

destroy() {
this._unlinkScopeProperties();
_.forEach(this._angularUnwatches, unwatch => {unwatch();});
_.forEach(this._connections, (descriptor, key) => {this._disconnect(key);});
this._vue.$destroy();
}
Expand Down Expand Up @@ -98,14 +91,7 @@ export default class Connector {
const connectionStats = stats.for(`connection.at.${key}`);
const getter = this._computeConnection.bind(this, fn, connectionStats);
const update = this._updateComputedConnection.bind(this, key, fn, connectionStats);
const angularWatch = angular.active && !fn.angularWatchSuppressed;
// Use this._vue.$watch instead of truss.observe here so that we can disable the immediate
// callback if we'll get one from Angular anyway.
this._vue.$watch(getter, update, {immediate: !angularWatch});
if (angularWatch) {
if (!this._angularUnwatches) this._angularUnwatches = [];
this._angularUnwatches.push(angular.watch(getter, update, true));
}
this._vue.$watch(getter, update, {immediate: true});
}

_computeConnection(fn, connectionStats) {
Expand Down Expand Up @@ -135,7 +121,6 @@ export default class Connector {
this._subConnectors[key]._updateConnections(newDescriptor);
}
Vue.set(this._vue.descriptors, key, newDescriptor);
angular.digest();
}

_updateConnections(connections) {
Expand All @@ -150,7 +135,6 @@ export default class Connector {

_connect(key, descriptor) {
Vue.set(this._vue.descriptors, key, descriptor);
angular.digest();
if (!descriptor) return;
Vue.set(this._vue.values, key, undefined);
if (descriptor instanceof Reference) {
Expand All @@ -175,7 +159,6 @@ export default class Connector {
unobserve();
delete this._disconnects[key];
Vue.set(this._vue.values, key, subScope);
angular.digest();
}
);
}
Expand All @@ -191,34 +174,29 @@ export default class Connector {
if (this._disconnects[key]) this._disconnects[key]();
delete this._disconnects[key];
Vue.delete(this._vue.descriptors, key);
angular.digest();
}

_updateRefValue(key, value) {
if (this._vue.values[key] !== value) {
Vue.set(this._vue.values, key, value);
angular.digest();
}
}

_updateQueryValue(key, childKeys) {
if (!this._vue.values[key]) {
Vue.set(this._vue.values, key, {});
angular.digest();
}
const subScope = this._vue.values[key];
for (const childKey in subScope) {
if (!Object.hasOwn(subScope, childKey)) continue;
if (!_.includes(childKeys, childKey)) {
Vue.delete(subScope, childKey);
angular.digest();
}
}
const object = this._tree.getObject(this._vue.descriptors[key].path);
for (const childKey of childKeys) {
if (Object.hasOwn(subScope, childKey)) continue;
Vue.set(subScope, childKey, object[childKey]);
angular.digest();
}
}

Expand All @@ -229,4 +207,3 @@ function flattenRefs(refs) {
if (refs instanceof Handle) return refs.toString();
return _.mapValues(refs, flattenRefs);
}

8 changes: 0 additions & 8 deletions src/Coupler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import _ from 'lodash';
import Vue from 'vue';
import angular from './angularCompatibility.js';
import {splitPath} from './utils/paths.js';


Expand Down Expand Up @@ -46,7 +45,6 @@ class QueryHandler {
this);
this._listening = false;
this.ready = false;
angular.digest();
for (const key of this._keys) {
this._coupler._decoupleSegments(this._segments.concat(key));
}
Expand All @@ -60,7 +58,6 @@ class QueryHandler {
const updatedKeys = this._updateKeysAndApplySnapshot(snap);
if (!this.ready) {
this.ready = true;
angular.digest();
for (const listener of this._listeners) {
this._coupler._dispatcher.markReady(listener.operation);
}
Expand Down Expand Up @@ -135,7 +132,6 @@ class QueryHandler {
this.ready = false;
for (const key of this._keys) this._coupler._decoupleSegments(this._segments.concat(key));
this._keys = [];
angular.digest();
Promise.all(_.map(this._listeners, listener => {
this._coupler._dispatcher.clearReady(listener.operation);
return this._coupler._dispatcher.retry(listener.operation, error).catch(e => {
Expand Down Expand Up @@ -196,7 +192,6 @@ class Node {
if (node.listening) return false;
if (node.ready) {
node.ready = false;
angular.digest();
}
});
} else {
Expand All @@ -210,7 +205,6 @@ class Node {
this._coupler._applySnapshot(snap);
if (!this.ready && snap.path === this.path) {
this.ready = true;
angular.digest();
this.unlisten(true);
this._forAllDescendants(node => {
for (const op of node.operations) this._coupler._dispatcher.markReady(op);
Expand All @@ -226,7 +220,6 @@ class Node {
if (node.listening) return false;
if (node.ready) {
node.ready = false;
angular.digest();
}
for (const op of node.operations) this._coupler._dispatcher.clearReady(op);
});
Expand Down Expand Up @@ -455,4 +448,3 @@ export default class Coupler {
}
}
}

4 changes: 0 additions & 4 deletions src/MetaTree.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import angular from './angularCompatibility.js';
import Vue from 'vue';
import Reference from './Reference.js';

Expand All @@ -16,7 +15,6 @@ export default class MetaTree {
if (!Object.hasOwn(this, key)) {
const update = () => {
Vue.set(this, key, Date.now() + this.timeOffset);
angular.digest();
};
update();
setInterval(update, intervalMillis);
Expand Down Expand Up @@ -84,7 +82,6 @@ export default class MetaTree {
if (user) Object.freeze(user);
this.root.user = user;
this.root.userid = user && user.uid;
angular.digest();
return true;
}
);
Expand All @@ -101,7 +98,6 @@ export default class MetaTree {
url.pathname = encodeURI(`/.info/${property}`);
this._bridge.on(url.href, url.href, null, 'value', snap => {
this.root[attribute] = snap.value;
angular.digest();
});
}
}
25 changes: 0 additions & 25 deletions src/Modeler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {Reference, Handle} from './Reference.js';
import angular from './angularCompatibility.js';
import stats from './utils/stats.js';
import {makePathMatcher, joinPath, splitPath, escapeKey, unescapeKey} from './utils/paths.js';
import {isTrussEqual, copyPrototype} from './utils/utils.js';
Expand Down Expand Up @@ -426,8 +425,6 @@ export default class Modeler {
const object = new mount.Class();
creatingObjectProperties = null;

if (angular.active) this._wrapProperties(object);

if (mount.keysUnsafe) {
properties.$data = {value: Object.create(null), configurable: true, enumerable: true};
}
Expand All @@ -445,24 +442,6 @@ export default class Modeler {
}
}

_wrapProperties(object) {
_.forEach(object, (value, key) => {
const valueKey = '$_' + key;
const descriptor = Object.getOwnPropertyDescriptor(object, key);
const valueDescriptor = descriptor.get && descriptor.set ? {
get: descriptor.get, set: descriptor.set, configurable: true
} : {value, writable: true};
Object.defineProperties(object, {
[valueKey]: valueDescriptor,
[key]: {
get: () => object[valueKey],
set: arg => {object[valueKey] = arg; angular.digest();},
enumerable: true, configurable: true
}
});
});
}

_buildComputedPropertyDescriptor(object, prop) {
const propertyStats = stats.for(prop.fullName);

Expand All @@ -486,15 +465,12 @@ export default class Modeler {
if (_.isObject(newValue) && _.isFunction(newValue.then)) {
const promise = newValue.then(finalValue => {
if (promise === pendingPromise) update(finalValue);
// No need to angular.digest() here, since if we're running under Angular then we expect
// promises to be aliased to its $q service, which triggers digest itself.
}, error => {
if (promise === pendingPromise && update(new ErrorWrapper(error)) &&
!error.trussExpectedException) throw error;
});
pendingPromise = promise;
} else if (update(newValue)) {
angular.digest();
if (newValue instanceof ErrorWrapper && !newValue.error.trussExpectedException) {
throw newValue.error;
}
Expand Down Expand Up @@ -710,7 +686,6 @@ function wrapConnections(object, connections) {
return wrapConnections(object, connections.call(this));
/* eslint-enable no-invalid-this */
};
fn.angularWatchSuppressed = true;
return fn;
}
return _.mapValues(connections, descriptor => wrapConnections(object, descriptor));
Expand Down
22 changes: 0 additions & 22 deletions src/Modeler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,28 +128,6 @@ test('computing non-primitive values', async () => {
tree.checkVueObject(tree.root, '/');
});

test('wrapping observed properties preserves missing child dependencies', async () => {
const tree = context.tree;
const navigationContext = {};
const navigation = {context: navigationContext};
const vue = new Vue({data: {navigation}});

tree._modeler._wrapProperties(navigation);
assert.equal(Object.hasOwn(navigation, '$_context'), true);

let review;
const unwatch = vue.$watch(() => navigation.context.review, value => {
review = value;
}, {immediate: true});
assert.equal(review, undefined);

Vue.set(navigationContext, 'review', {ready: true});
await Vue.nextTick();
assert.deepEqual(review, {ready: true});
unwatch();
vue.$destroy();
});

test('computed properties added after observation remain reactive', async () => {
const tree = new Tree(
context.truss, context.rootUrl, context.bridge, context.dispatcher);
Expand Down
4 changes: 0 additions & 4 deletions src/Tree.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import angular from './angularCompatibility.js';
import Coupler from './Coupler.js';
import Modeler from './Modeler.js';
import Reference from './Reference.js';
Expand Down Expand Up @@ -75,7 +74,6 @@ export default class Tree {
this._vue.$data.$root = this._createObject('/');
this._fixObject(this._vue.$data.$root);
this._completeCreateObject(this._vue.$data.$root);
angular.digest();
}
return this._vue.$data.$root;
}
Expand Down Expand Up @@ -645,7 +643,6 @@ export default class Tree {
configurable: true, enumerable: !hidden
});
}
angular.digest();
}

_overwriteFirebaseProperty(descriptor, key, newValue) {
Expand All @@ -663,7 +660,6 @@ export default class Tree {
this._getFirebasePropertyDescriptor(object, data, key);
this._destroyObject(data[key]);
Vue.delete(data, key);
angular.digest();
}

checkVueObject(object, path) {
Expand Down
Loading