Skip to content

Commit 2fd5c2e

Browse files
committed
Use Meteor to store todos.
1 parent fe4d9d0 commit 2fd5c2e

File tree

7 files changed

+350
-81
lines changed

7 files changed

+350
-81
lines changed

.meteor/packages

+10-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,16 @@ [email protected] # ECMAScript 5 compatibility for older browsers.
1616
ecmascript # Enable ECMAScript2015+ syntax in app code
1717
[email protected] # Server-side component of the `meteor shell` command
1818

19-
akryum:vue-component
20-
static-html
2119
dynamic-import
20+
static-html
21+
22+
akryum:vue-component
2223
fourseven:scss
2324
akryum:vue-router2
25+
check
26+
audit-argument-checks
27+
mdg:validated-method
28+
peerlibrary:check-extension
29+
peerlibrary:subscription-scope
30+
peerlibrary:subscription-data
31+
peerlibrary:reactive-publish

.meteor/versions

+14

client/meteor.js

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import Vue from 'vue';
2+
3+
// To not have dependency on underscore.
4+
function isEmpty(object) {
5+
for (const name in object) {
6+
if (object.hasOwnProperty(name)) {
7+
return true;
8+
}
9+
}
10+
return false;
11+
}
12+
13+
Vue.use({
14+
install(Vue, options) {
15+
Vue.mixin({
16+
beforeCreate() {
17+
this._onDestroyedCallbacks = [];
18+
19+
this._allSubsReadyDep = new Tracker.Dependency();
20+
this._allSubsReady = false;
21+
this._subscriptionHandles = new Map();
22+
},
23+
24+
destroyed() {
25+
while (this._onDestroyedCallbacks.length) {
26+
const callback = this._onDestroyedCallbacks.shift();
27+
if (callback) {
28+
callback();
29+
}
30+
}
31+
}
32+
});
33+
34+
function addOnDestroyedCallback(callbacks, callback) {
35+
callbacks.push(callback);
36+
}
37+
38+
function removeOnDestroyedCallback (callbacks, callback) {
39+
const index = callbacks.lastIndexOf(callback);
40+
if (index !== -1) {
41+
callbacks.splice(index, 1);
42+
}
43+
}
44+
45+
Vue.prototype.$autorun = function (f) {
46+
const vm = this;
47+
const computation = Tracker.nonreactive(() => {
48+
return Tracker.autorun((computation) => {
49+
f.call(vm, computation);
50+
});
51+
});
52+
53+
const stopComputation = function () {
54+
computation.stop();
55+
};
56+
57+
addOnDestroyedCallback(this._onDestroyedCallbacks, stopComputation);
58+
computation.onStop(() => {
59+
removeOnDestroyedCallback(this._onDestroyedCallbacks, stopComputation);
60+
});
61+
62+
return computation;
63+
};
64+
65+
Vue.prototype.$subscribe = function (/* arguments */) {
66+
const args = Array.prototype.slice.call(arguments);
67+
68+
// Duplicate logic from Meteor.subscribe.
69+
let options = {};
70+
if (args.length) {
71+
const lastParam = args[args.length - 1];
72+
73+
// Match pattern to check if the last arg is an options argument.
74+
const lastParamOptionsPattern = {
75+
onReady: Match.Optional(Function),
76+
onStop: Match.Optional(Function),
77+
connection: Match.Optional(Match.Any),
78+
};
79+
80+
if (typeof lastParam === 'function') {
81+
options.onReady = args.pop();
82+
}
83+
else if (lastParam && !isEmpty(lastParam) && Match.test(lastParam, lastParamOptionsPattern)) {
84+
options = args.pop();
85+
}
86+
}
87+
88+
const oldStopped = options.onStop;
89+
options.onStop = (error) => {
90+
// When the subscription is stopped, remove it from the set of tracked
91+
// subscriptions to avoid this list growing without bound.
92+
this._subscriptionHandles.delete(subHandle.subscriptionId);
93+
removeOnDestroyedCallback(this._onDestroyedCallbacks, stopHandle);
94+
95+
// Removing a subscription can only change the result of subscriptionsReady
96+
// if we are not ready (that subscription could be the one blocking us being
97+
// ready).
98+
if (!this._allSubsReady) {
99+
this._allSubsReadyDep.changed();
100+
}
101+
102+
if (oldStopped) {
103+
oldStopped(error);
104+
}
105+
};
106+
107+
const callbacks = {};
108+
if (options.hasOwnProperty('onReady')) {
109+
callbacks.onReady = options.onReady;
110+
}
111+
if (options.hasOwnProperty('onStop')) {
112+
callbacks.onStop = options.onStop;
113+
}
114+
115+
args.push(callbacks);
116+
117+
let subHandle;
118+
if (options.connection) {
119+
subHandle = options.connection.subscribe.apply(options.connection, args);
120+
}
121+
else {
122+
subHandle = Meteor.subscribe.apply(Meteor, args);
123+
}
124+
125+
const stopHandle = function () {
126+
subHandle.stop();
127+
};
128+
129+
addOnDestroyedCallback(this._onDestroyedCallbacks, stopHandle);
130+
131+
if (!this._subscriptionHandles.has(subHandle.subscriptionId)) {
132+
this._subscriptionHandles.set(subHandle.subscriptionId, subHandle);
133+
134+
// Adding a new subscription will always cause us to transition from ready
135+
// to not ready, but if we are already not ready then this can't make us
136+
// ready.
137+
if (this._allSubsReady) {
138+
this._allSubsReadyDep.changed();
139+
}
140+
}
141+
142+
return subHandle;
143+
};
144+
145+
Vue.prototype.$subscriptionsReady = function () {
146+
this._allSubsReadyDep.depend();
147+
148+
this._allSubsReady = this._subscriptionHandles.every(function (handle, index, array) {
149+
return handle.ready();
150+
});
151+
152+
return this._allSubsReady;
153+
};
154+
}
155+
});

0 commit comments

Comments
 (0)