mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Move random generation code from minimongo and uuid packages to new random
package. The new API is Random.id(), Random.fraction(), Random.choice(arrayOrString), and Random.hexString(digits). Meteor.uuid is kept around for backwards compatibility.
This commit is contained in:
@@ -9,7 +9,7 @@ PACKAGES_DIR=`dirname $0`/../packages
|
||||
echo 'Meteor = {};'
|
||||
cat $PACKAGES_DIR/underscore/underscore.js
|
||||
cat $PACKAGES_DIR/logging/logging.js
|
||||
cat $PACKAGES_DIR/uuid/uuid.js
|
||||
cat $PACKAGES_DIR/random/random.js
|
||||
cat $PACKAGES_DIR/deps/deps.js
|
||||
cat $PACKAGES_DIR/deps/deps-utils.js
|
||||
cat $PACKAGES_DIR/liverange/liverange.js
|
||||
|
||||
@@ -1034,25 +1034,6 @@ Example:
|
||||
// After five seconds, stop keeping the count.
|
||||
setTimeout(function () {handle.stop();}, 5000);
|
||||
|
||||
{{> api_box id}}
|
||||
|
||||
This returns a random text string such as ``"Jjwjg6gouWLXhMGKW"``
|
||||
that is likely to be unique in the whole world.
|
||||
|
||||
Currently Meteor uses this function to generate `_id` fields for new Mongo
|
||||
documents by default. If your database requires native binary Mongo IDs instead,
|
||||
pass `"MONGO"` as the `idGeneration` option to
|
||||
[`Meteor.Collection`](#meteor_collection).
|
||||
|
||||
|
||||
{{#note}}
|
||||
|
||||
In the current implementation, the returned string is derived from a
|
||||
pseudorandom number generator. The IDs generated definitely are not random
|
||||
enough to be used for cryptographic or security purposes.
|
||||
|
||||
{{/note}}
|
||||
|
||||
{{> api_box collection_object_id}}
|
||||
|
||||
`Meteor.Collection.ObjectID` follows the same API as the [Node MongoDB driver
|
||||
@@ -1500,7 +1481,7 @@ Example:
|
||||
|
||||
// Support for playing D&D: Roll 3d6 for dexterity
|
||||
Accounts.onCreateUser(function(options, user) {
|
||||
var d6 = function () { return Math.floor(Math.random() * 6) + 1; };
|
||||
var d6 = function () { return Math.floor(Random.fraction() * 6) + 1; };
|
||||
user.dexterity = d6() + d6() + d6();
|
||||
// We still want the default hook's 'profile' behavior.
|
||||
if (options.profile)
|
||||
|
||||
@@ -684,7 +684,7 @@ Template.api.cursor_observe_changes = {
|
||||
|
||||
Template.api.id = {
|
||||
id: "meteor_id",
|
||||
name: "Meteor.id()",
|
||||
name: "Random.id()",
|
||||
locus: "Anywhere",
|
||||
descr: ["Return a unique identifier."],
|
||||
args: [ ]
|
||||
|
||||
@@ -151,7 +151,6 @@ var toc = [
|
||||
{instance: "cursor", name: "observeChanges", id: "observe_changes"}
|
||||
],
|
||||
{type: "spacer"},
|
||||
"Meteor.id",
|
||||
{name: "Meteor.Collection.ObjectID", id: "collection_object_id"},
|
||||
{type: "spacer"},
|
||||
{name: "Selectors", style: "noncode"},
|
||||
@@ -295,6 +294,7 @@ var toc = [
|
||||
"force-ssl",
|
||||
"jquery",
|
||||
"less",
|
||||
"random",
|
||||
"spiderable",
|
||||
"stylus",
|
||||
"showdown",
|
||||
|
||||
@@ -25,6 +25,7 @@ and removed with:
|
||||
{{> pkg_force_ssl}}
|
||||
{{> pkg_jquery}}
|
||||
{{> pkg_less}}
|
||||
{{> pkg_random}}
|
||||
{{> pkg_spiderable}}
|
||||
{{> pkg_stylus}}
|
||||
{{> pkg_showdown}}
|
||||
|
||||
34
docs/client/packages/random.html
Normal file
34
docs/client/packages/random.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<template name="pkg_random">
|
||||
{{#better_markdown}}
|
||||
## `random`
|
||||
|
||||
The `random` package provides several random-number utilities, using a
|
||||
random-number generator whose implementation does not depend on the particular
|
||||
browser.
|
||||
|
||||
<dl class="callbacks">
|
||||
{{#dtdd "Random.id()"}}
|
||||
Returns a unique identifier, such as `"Jjwjg6gouWLXhMGKW"`, that is likely to
|
||||
be unique in the whole world.
|
||||
{{/dtdd}}
|
||||
|
||||
{{#dtdd "Random.fraction()"}}
|
||||
Returns a number between 0 and 1, like `Math.random`.
|
||||
{{/dtdd}}
|
||||
|
||||
{{#dtdd "Random.choice(arrayOrString)"}}
|
||||
Returns a random element of the given array or string.
|
||||
{{/dtdd}}
|
||||
|
||||
{{#dtdd "Random.hexString(n)"}}
|
||||
Returns a random string of `n` hexadecimal digits.
|
||||
{{/dtdd}}
|
||||
</dl>
|
||||
|
||||
{{#note}}
|
||||
In the current implementation, random values do not come from a
|
||||
cryptographically strong pseudorandom number generator. Future releases will
|
||||
improve this, particularly on the server.
|
||||
{{/note}}
|
||||
{{/better_markdown}}
|
||||
</template>
|
||||
@@ -6,3 +6,4 @@
|
||||
autopublish
|
||||
insecure
|
||||
preserve-inputs
|
||||
random
|
||||
|
||||
@@ -41,7 +41,7 @@ if (Meteor.isServer) {
|
||||
"Nikola Tesla",
|
||||
"Claude Shannon"];
|
||||
for (var i = 0; i < names.length; i++)
|
||||
Players.insert({name: names[i], score: Math.floor(Math.random()*10)*5});
|
||||
Players.insert({name: names[i], score: Math.floor(Random.fraction()*10)*5});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
insecure
|
||||
preserve-inputs
|
||||
random
|
||||
|
||||
@@ -69,7 +69,7 @@ if (Meteor.isServer) {
|
||||
};
|
||||
Template.updated.events({
|
||||
'click #update-button': function () {
|
||||
var num = Math.round(Math.random()*100);
|
||||
var num = Math.round(Random.fraction()*100);
|
||||
Meteor.call('setMagic', num);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -150,12 +150,12 @@ Template.circles.events({
|
||||
Session.set("selectedCircle:" + this.group, evt.currentTarget.id);
|
||||
},
|
||||
'click .add': function () {
|
||||
Circles.insert({x: Meteor.random(), y: Meteor.random(),
|
||||
r: Meteor.random() * .1 + .02,
|
||||
Circles.insert({x: Random.fraction(), y: Random.fraction(),
|
||||
r: Random.fraction() * .1 + .02,
|
||||
color: {
|
||||
r: Meteor.random(),
|
||||
g: Meteor.random(),
|
||||
b: Meteor.random()
|
||||
r: Random.fraction(),
|
||||
g: Random.fraction(),
|
||||
b: Random.fraction()
|
||||
},
|
||||
group: this.group
|
||||
});
|
||||
@@ -171,7 +171,7 @@ Template.circles.events({
|
||||
Circles.find({group: this.group}).forEach(function (r) {
|
||||
Circles.update(r._id, {
|
||||
$set: {
|
||||
x: Meteor.random(), y: Meteor.random(), r: Meteor.random() * .1 + .02
|
||||
x: Random.fraction(), y: Random.fraction(), r: Random.fraction() * .1 + .02
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ if (Meteor.isClient) {
|
||||
} else {
|
||||
// make sure we have a username
|
||||
Meteor.users.update(Meteor.userId(),
|
||||
{ $set: { username: Meteor.uuid() }});
|
||||
{ $set: { username: Random.id() }});
|
||||
}
|
||||
}
|
||||
} else if (key === "signupFields") {
|
||||
@@ -116,7 +116,7 @@ if (Meteor.isClient) {
|
||||
|
||||
var fakeLogin = function (callback) {
|
||||
Accounts.createUser(
|
||||
{username: Meteor.uuid(),
|
||||
{username: Random.id(),
|
||||
password: "password",
|
||||
profile: { name: "Joe Schmoe" }},
|
||||
function () {
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
insecure
|
||||
preserve-inputs
|
||||
bootstrap
|
||||
random
|
||||
|
||||
@@ -16,7 +16,7 @@ if (Meteor.isServer) {
|
||||
//////////////////////////////
|
||||
|
||||
var random = function (n) {
|
||||
return Math.floor(Math.random() * n);
|
||||
return Math.floor(Random.fraction() * n);
|
||||
};
|
||||
|
||||
var randomChars =
|
||||
@@ -25,13 +25,13 @@ var randomString = function (length) {
|
||||
// XXX make more efficient
|
||||
var ret = '';
|
||||
_.times(length, function () {
|
||||
ret += randomChars[random(randomChars.length)];
|
||||
ret += Random.choice(randomChars);
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
var pickCollection = function () {
|
||||
return Collections[random(Collections.length)];
|
||||
return Random.choice(Collections);
|
||||
};
|
||||
|
||||
var generateDoc = function () {
|
||||
@@ -123,7 +123,7 @@ if (Meteor.isClient) {
|
||||
Meteor.setInterval(function () {
|
||||
var C = pickCollection();
|
||||
var docs = C.find({}).fetch();
|
||||
var doc = docs[random(docs.length)];
|
||||
var doc = Random.choice(docs);
|
||||
if (doc)
|
||||
C.remove(doc._id);
|
||||
}, 1000 / PARAMS.removesPerSecond);
|
||||
@@ -133,7 +133,7 @@ if (Meteor.isClient) {
|
||||
Meteor.setInterval(function () {
|
||||
var C = pickCollection();
|
||||
var docs = C.find({}).fetch();
|
||||
var doc = docs[random(docs.length)];
|
||||
var doc = Random.choice(docs);
|
||||
if (doc) {
|
||||
var field = 'Field' + random(PARAMS.documentNumFields);
|
||||
var modifer = {};
|
||||
|
||||
@@ -44,7 +44,7 @@ var new_board = function () {
|
||||
|
||||
// pick random letter from each die
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
board[i] = DICE[i].split('')[Math.floor(Math.random() * 6)];
|
||||
board[i] = Random.choice(DICE[i]);
|
||||
}
|
||||
|
||||
// knuth shuffle
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
// support reconnecting using a meteor login token
|
||||
Accounts._generateStampedLoginToken = function () {
|
||||
return {token: Meteor.uuid(), when: +(new Date)};
|
||||
return {token: Random.id(), when: +(new Date)};
|
||||
};
|
||||
|
||||
Accounts.registerLoginHandler(function(options) {
|
||||
|
||||
@@ -8,7 +8,7 @@ Tinytest.add('accounts - config validates keys', function (test) {
|
||||
});
|
||||
|
||||
Tinytest.add('accounts - updateOrCreateUserFromExternalService - Facebook', function (test) {
|
||||
var facebookId = Meteor.uuid();
|
||||
var facebookId = Random.id();
|
||||
|
||||
// create an account with facebook
|
||||
var uid1 = Accounts.updateOrCreateUserFromExternalService(
|
||||
@@ -38,8 +38,8 @@ Tinytest.add('accounts - updateOrCreateUserFromExternalService - Facebook', func
|
||||
});
|
||||
|
||||
Tinytest.add('accounts - updateOrCreateUserFromExternalService - Weibo', function (test) {
|
||||
var weiboId1 = Meteor.uuid();
|
||||
var weiboId2 = Meteor.uuid();
|
||||
var weiboId1 = Random.id();
|
||||
var weiboId2 = Random.id();
|
||||
|
||||
// users that have different service ids get different users
|
||||
uid1 = Accounts.updateOrCreateUserFromExternalService(
|
||||
@@ -85,7 +85,7 @@ Tinytest.add('accounts - updateOrCreateUserFromExternalService - Twitter', funct
|
||||
|
||||
Tinytest.add('accounts - insertUserDoc username', function (test) {
|
||||
var userIn = {
|
||||
username: Meteor.uuid()
|
||||
username: Random.id()
|
||||
};
|
||||
|
||||
// user does not already exist. create a user object with fields set.
|
||||
@@ -113,9 +113,9 @@ Tinytest.add('accounts - insertUserDoc username', function (test) {
|
||||
});
|
||||
|
||||
Tinytest.add('accounts - insertUserDoc email', function (test) {
|
||||
var email1 = Meteor.uuid();
|
||||
var email2 = Meteor.uuid();
|
||||
var email3 = Meteor.uuid();
|
||||
var email1 = Random.id();
|
||||
var email2 = Random.id();
|
||||
var email3 = Random.id();
|
||||
var userIn = {
|
||||
emails: [{address: email1, verified: false},
|
||||
{address: email2, verified: true}]
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
// logging in and out, to protect multiple tabs running the same tests
|
||||
// simultaneously from interfering with each others' localStorage.
|
||||
Accounts._isolateLoginTokenForTest = function () {
|
||||
loginTokenKey = loginTokenKey + Meteor.uuid();
|
||||
userIdKey = userIdKey + Meteor.uuid();
|
||||
loginTokenKey = loginTokenKey + Random.id();
|
||||
userIdKey = userIdKey + Random.id();
|
||||
};
|
||||
|
||||
Accounts._storeLoginToken = function(userId, token) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var state = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
|
||||
var display = mobile ? 'touch' : 'popup';
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
callback && callback(new Accounts.ConfigError("Service not configured"));
|
||||
return;
|
||||
}
|
||||
var state = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
|
||||
var scope = (options && options.requestPermissions) || [];
|
||||
var flatScope = _.map(scope, encodeURIComponent).join('+');
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var state = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
|
||||
// always need this to get user id from google.
|
||||
var requiredScope = ['https://www.googleapis.com/auth/userinfo.profile'];
|
||||
|
||||
@@ -78,7 +78,7 @@ OAuth1Binding.prototype._buildHeader = function(headers) {
|
||||
var self = this;
|
||||
return _.extend({
|
||||
oauth_consumer_key: self._consumerKey,
|
||||
oauth_nonce: Meteor.uuid().replace(/\W/g, ''),
|
||||
oauth_nonce: Random.id().replace(/\W/g, ''),
|
||||
oauth_signature_method: 'HMAC-SHA1',
|
||||
oauth_timestamp: (new Date().valueOf()/1000).toFixed().toString(),
|
||||
oauth_version: '1.0'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
Tinytest.add("oauth1 - loginResultForState is stored", function (test) {
|
||||
var http = __meteor_bootstrap__.require('http');
|
||||
var twitterfooId = Meteor.uuid();
|
||||
var twitterfooName = 'nickname' + Meteor.uuid();
|
||||
var twitterfooAccessToken = Meteor.uuid();
|
||||
var twitterfooAccessTokenSecret = Meteor.uuid();
|
||||
var state = Meteor.uuid();
|
||||
var twitterfooId = Random.id();
|
||||
var twitterfooName = 'nickname' + Random.id();
|
||||
var twitterfooAccessToken = Random.id();
|
||||
var twitterfooAccessTokenSecret = Random.id();
|
||||
var state = Random.id();
|
||||
|
||||
OAuth1Binding.prototype.prepareRequestToken = function() {};
|
||||
OAuth1Binding.prototype.prepareAccessToken = function() {
|
||||
@@ -70,11 +70,11 @@ Tinytest.add("oauth1 - loginResultForState is stored", function (test) {
|
||||
|
||||
Tinytest.add("oauth1 - error in user creation", function (test) {
|
||||
var http = __meteor_bootstrap__.require('http');
|
||||
var state = Meteor.uuid();
|
||||
var twitterfailId = Meteor.uuid();
|
||||
var twitterfailName = 'nickname' + Meteor.uuid();
|
||||
var twitterfailAccessToken = Meteor.uuid();
|
||||
var twitterfailAccessTokenSecret = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
var twitterfailId = Random.id();
|
||||
var twitterfailName = 'nickname' + Random.id();
|
||||
var twitterfailAccessToken = Random.id();
|
||||
var twitterfailAccessTokenSecret = Random.id();
|
||||
|
||||
if (!Accounts.loginServiceConfiguration.findOne({service: 'twitterfail'}))
|
||||
Accounts.loginServiceConfiguration.insert({service: 'twitterfail'});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Tinytest.add("oauth2 - loginResultForState is stored", function (test) {
|
||||
var http = __meteor_bootstrap__.require('http');
|
||||
var foobookId = Meteor.uuid();
|
||||
var state = Meteor.uuid();
|
||||
var foobookId = Random.id();
|
||||
var state = Random.id();
|
||||
|
||||
if (!Accounts.loginServiceConfiguration.findOne({service: 'foobook'}))
|
||||
Accounts.loginServiceConfiguration.insert({service: 'foobook'});
|
||||
@@ -42,8 +42,8 @@ Tinytest.add("oauth2 - loginResultForState is stored", function (test) {
|
||||
|
||||
Tinytest.add("oauth2 - error in user creation", function (test) {
|
||||
var http = __meteor_bootstrap__.require('http');
|
||||
var state = Meteor.uuid();
|
||||
var failbookId = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
var failbookId = Random.id();
|
||||
|
||||
if (!Accounts.loginServiceConfiguration.findOne({service: 'failbook'}))
|
||||
Accounts.loginServiceConfiguration.insert({service: 'failbook'});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
testAsyncMulti("accounts emails - reset password flow", [
|
||||
function (test, expect) {
|
||||
email1 = Meteor.uuid() + "-intercept@example.com";
|
||||
email1 = Random.id() + "-intercept@example.com";
|
||||
Accounts.createUser({email: email1, password: 'foobar'},
|
||||
expect(function (error) {
|
||||
test.equal(error, undefined);
|
||||
@@ -87,8 +87,8 @@
|
||||
|
||||
testAsyncMulti("accounts emails - verify email flow", [
|
||||
function (test, expect) {
|
||||
email2 = Meteor.uuid() + "-intercept@example.com";
|
||||
email3 = Meteor.uuid() + "-intercept@example.com";
|
||||
email2 = Random.id() + "-intercept@example.com";
|
||||
email3 = Random.id() + "-intercept@example.com";
|
||||
Accounts.createUser(
|
||||
{email: email2, password: 'foobar'},
|
||||
loggedIn(test, expect));
|
||||
@@ -171,7 +171,7 @@
|
||||
|
||||
testAsyncMulti("accounts emails - enroll account flow", [
|
||||
function (test, expect) {
|
||||
email4 = Meteor.uuid() + "-intercept@example.com";
|
||||
email4 = Random.id() + "-intercept@example.com";
|
||||
Meteor.call("createUserOnServer", email4,
|
||||
expect(function (error, result) {
|
||||
test.isFalse(error);
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// user: either {username: (username)}, {email: (email)}, or {id: (userId)}
|
||||
// A: hex encoded int. the client's public key for this exchange
|
||||
// @returns {Object} with fields:
|
||||
// identiy: string uuid
|
||||
// salt: string uuid
|
||||
// identity: random string ID
|
||||
// salt: random string ID
|
||||
// B: hex encoded int. server's public key for this exchange
|
||||
beginPasswordExchange: function (request) {
|
||||
var selector = selectorFromUserQuery(request.user);
|
||||
@@ -191,7 +191,7 @@
|
||||
if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email))
|
||||
throw new Error("No such email for user.");
|
||||
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
var when = +(new Date);
|
||||
Meteor.users.update(userId, {$set: {
|
||||
"services.password.reset": {
|
||||
@@ -233,7 +233,7 @@
|
||||
|
||||
|
||||
var tokenRecord = {
|
||||
token: Meteor.uuid(),
|
||||
token: Random.id(),
|
||||
address: address,
|
||||
when: +(new Date)};
|
||||
Meteor.users.update(
|
||||
@@ -268,7 +268,7 @@
|
||||
throw new Error("No such email for user.");
|
||||
|
||||
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
var when = +(new Date);
|
||||
Meteor.users.update(userId, {$set: {
|
||||
"services.password.reset": {
|
||||
|
||||
@@ -28,11 +28,11 @@ if (Meteor.isClient) (function () {
|
||||
|
||||
testAsyncMulti("passwords - long series", [
|
||||
function (test, expect) {
|
||||
username = Meteor.uuid();
|
||||
username2 = Meteor.uuid();
|
||||
username3 = Meteor.uuid();
|
||||
username = Random.id();
|
||||
username2 = Random.id();
|
||||
username3 = Random.id();
|
||||
// use -intercept so that we don't print to the console
|
||||
email = Meteor.uuid() + '-intercept@example.com';
|
||||
email = Random.id() + '-intercept@example.com';
|
||||
password = 'password';
|
||||
password2 = 'password2';
|
||||
password3 = 'password3';
|
||||
@@ -227,7 +227,7 @@ if (Meteor.isServer) (function () {
|
||||
Tinytest.add(
|
||||
'passwords - createUser hooks',
|
||||
function (test) {
|
||||
var email = Meteor.uuid() + '@example.com';
|
||||
var email = Random.id() + '@example.com';
|
||||
test.throws(function () {
|
||||
// should fail the new user validators
|
||||
Accounts.createUser({email: email, profile: {invalid: true}});
|
||||
@@ -249,7 +249,7 @@ if (Meteor.isServer) (function () {
|
||||
Tinytest.add(
|
||||
'passwords - setPassword',
|
||||
function (test) {
|
||||
var username = Meteor.uuid();
|
||||
var username = Random.id();
|
||||
|
||||
var userId = Accounts.createUser({username: username});
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var state = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
// We need to keep state across the next two 'steps' so we're adding
|
||||
// a state parameter to the url and the callback url that we'll be returned
|
||||
// to by oauth provider
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var state = Meteor.uuid();
|
||||
var state = Random.id();
|
||||
// XXX need to support configuring access_type and scope
|
||||
var loginUrl =
|
||||
'https://api.weibo.com/oauth2/authorize' +
|
||||
|
||||
@@ -98,7 +98,7 @@ testAsyncMulti("httpcall - timeout", [
|
||||
|
||||
// Should time out
|
||||
Meteor.http.call(
|
||||
"GET", url_prefix()+"/slow-"+Meteor.uuid(),
|
||||
"GET", url_prefix()+"/slow-"+Random.id(),
|
||||
{ timeout: 500 },
|
||||
expect(function(error, result) {
|
||||
test.isTrue(error);
|
||||
@@ -107,7 +107,7 @@ testAsyncMulti("httpcall - timeout", [
|
||||
|
||||
// Should not time out
|
||||
Meteor.http.call(
|
||||
"GET", url_prefix()+"/foo-"+Meteor.uuid(),
|
||||
"GET", url_prefix()+"/foo-"+Random.id(),
|
||||
{ timeout: 2000 },
|
||||
expect(function(error, result) {
|
||||
test.isFalse(error);
|
||||
@@ -254,7 +254,7 @@ testAsyncMulti("httpcall - http auth", [
|
||||
// uses cached credentials even if we supply different ones:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=654348
|
||||
var password = 'rocks';
|
||||
//var password = Meteor.uuid().replace(/[^0-9a-zA-Z]/g, '');
|
||||
//var password = Random.id().replace(/[^0-9a-zA-Z]/g, '');
|
||||
Meteor.http.call(
|
||||
"GET", url_prefix()+"/login?"+password,
|
||||
{ auth: "meteor:"+password },
|
||||
|
||||
@@ -469,7 +469,7 @@ _.extend(Meteor._LivedataConnection.prototype, {
|
||||
}
|
||||
} else {
|
||||
// New sub! Generate an id, save it locally, and send message.
|
||||
id = Meteor.uuid();
|
||||
id = Random.id();
|
||||
self._subscriptions[id] = {
|
||||
id: id,
|
||||
name: name,
|
||||
|
||||
@@ -74,7 +74,7 @@ Tinytest.add("livedata stub - receive data", function (test) {
|
||||
startAndConnect(test, stream);
|
||||
|
||||
// data comes in for unknown collection.
|
||||
var coll_name = Meteor.uuid();
|
||||
var coll_name = Random.id();
|
||||
stream.receive({msg: 'added', collection: coll_name, id: '1234',
|
||||
fields: {a: 1}});
|
||||
// break throught the black box and test internal state
|
||||
@@ -294,7 +294,7 @@ Tinytest.add("livedata stub - methods", function (test) {
|
||||
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
|
||||
// setup method
|
||||
@@ -436,7 +436,7 @@ Tinytest.add("livedata stub - methods calling methods", function (test) {
|
||||
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var coll_name = Meteor.uuid();
|
||||
var coll_name = Random.id();
|
||||
var coll = new Meteor.Collection(coll_name, {manager: conn});
|
||||
|
||||
// setup methods
|
||||
@@ -521,7 +521,7 @@ Tinytest.add("livedata stub - reconnect", function (test) {
|
||||
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
|
||||
var o = observeCursor(test, coll.find());
|
||||
@@ -646,7 +646,7 @@ Tinytest.add("livedata stub - reconnect method which only got result", function
|
||||
var conn = newConnection(stream);
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
var o = observeCursor(test, coll.find());
|
||||
|
||||
@@ -819,7 +819,7 @@ Tinytest.add("livedata stub - reconnect method which only got data", function (t
|
||||
var conn = newConnection(stream);
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
var o = observeCursor(test, coll.find());
|
||||
|
||||
@@ -906,7 +906,7 @@ Tinytest.add("livedata stub - multiple stubs same doc", function (test) {
|
||||
var conn = newConnection(stream);
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
var o = observeCursor(test, coll.find());
|
||||
|
||||
@@ -991,7 +991,7 @@ Tinytest.add("livedata stub - unsent methods don't block quiescence", function (
|
||||
var conn = newConnection(stream);
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
|
||||
conn.methods({
|
||||
@@ -1067,7 +1067,7 @@ Tinytest.add("livedata connection - two wait methods", function (test) {
|
||||
var conn = newConnection(stream);
|
||||
startAndConnect(test, stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
|
||||
// setup method
|
||||
@@ -1320,7 +1320,7 @@ Tinytest.add("livedata connection - onReconnect with sent messages", function(te
|
||||
params: ['login'], id: '*'});
|
||||
|
||||
// we connect.
|
||||
stream.receive({msg: 'connected', session: Meteor.uuid()});
|
||||
stream.receive({msg: 'connected', session: Random.id()});
|
||||
test.length(stream.sent, 0);
|
||||
|
||||
// login got result (but not yet data)
|
||||
@@ -1446,7 +1446,7 @@ Tinytest.add("livedata stub - stubs before connected", function (test) {
|
||||
var stream = new Meteor._StubStream();
|
||||
var conn = newConnection(stream);
|
||||
|
||||
var collName = Meteor.uuid();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
|
||||
// Start and send "connect", but DON'T get 'connected' quite yet.
|
||||
|
||||
@@ -201,7 +201,7 @@ _.extend(Meteor._SessionCollectionView.prototype, {
|
||||
|
||||
Meteor._LivedataSession = function (server, version) {
|
||||
var self = this;
|
||||
self.id = Meteor.uuid();
|
||||
self.id = Random.id();
|
||||
|
||||
self.server = server;
|
||||
self.version = version;
|
||||
@@ -772,7 +772,7 @@ Meteor._LivedataSubscription = function (
|
||||
if (self._subscriptionId) {
|
||||
self._subscriptionHandle = 'N' + self._subscriptionId;
|
||||
} else {
|
||||
self._subscriptionHandle = 'U' + Meteor.id();
|
||||
self._subscriptionHandle = 'U' + Random.id();
|
||||
}
|
||||
|
||||
// has _deactivate been called?
|
||||
|
||||
@@ -244,7 +244,7 @@ if (Meteor.isServer) {
|
||||
// First add a random item, which should be cleaned up. We use ready/onReady
|
||||
// to make sure that the second test block is only called after the added is
|
||||
// processed, so that there's any chance of the coll.find().count() failing.
|
||||
sub.added(collName, Meteor.id(), {foo: 42});
|
||||
sub.added(collName, Random.id(), {foo: 42});
|
||||
sub.ready();
|
||||
|
||||
if (options.stopInHandler) {
|
||||
|
||||
@@ -45,7 +45,7 @@ if (Meteor.isServer) {
|
||||
}
|
||||
|
||||
Tinytest.add("livedata - methods with colliding names", function (test) {
|
||||
var x = LocalCollection.uuid();
|
||||
var x = Random.id();
|
||||
var m = {};
|
||||
m[x] = function () {};
|
||||
Meteor.methods(m);
|
||||
@@ -137,7 +137,7 @@ testAsyncMulti("livedata - basic method invocation", [
|
||||
function (test, expect) {
|
||||
if (Meteor.isClient) {
|
||||
// For test isolation
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
Meteor.apply(
|
||||
"delayedTrue", [token], {wait: false}, expect(function(err, res) {
|
||||
test.equal(res, false);
|
||||
@@ -149,7 +149,7 @@ testAsyncMulti("livedata - basic method invocation", [
|
||||
// test that `wait: true` is respected
|
||||
function(test, expect) {
|
||||
if (Meteor.isClient) {
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
Meteor.apply(
|
||||
"delayedTrue", [token], {wait: true}, expect(function(err, res) {
|
||||
test.equal(res, true);
|
||||
@@ -378,7 +378,7 @@ if (Meteor.isClient) {
|
||||
undoEavesdrop();
|
||||
});
|
||||
}, function(test, expect) {
|
||||
var key = Meteor.uuid();
|
||||
var key = Random.id();
|
||||
Meteor.subscribe("recordUserIdOnStop", key);
|
||||
Meteor.apply("setUserId", [100], {wait: true}, expect(function () {}));
|
||||
Meteor.apply("setUserId", [101], {wait: true}, expect(function () {}));
|
||||
@@ -401,7 +401,7 @@ if (Meteor.isClient) {
|
||||
testAsyncMulti("livedata - overlapping universal subs", [
|
||||
function (test, expect) {
|
||||
var coll = new Meteor.Collection("overlappingUniversalSubs");
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
test.isFalse(coll.findOne(token));
|
||||
Meteor.call("testOverlappingSubs", token, expect(function (err) {
|
||||
test.isFalse(err);
|
||||
@@ -413,7 +413,7 @@ if (Meteor.isClient) {
|
||||
testAsyncMulti("livedata - runtime universal sub creation", [
|
||||
function (test, expect) {
|
||||
var coll = new Meteor.Collection("runtimeSubCreation");
|
||||
var token = Meteor.uuid();
|
||||
var token = Random.id();
|
||||
test.isFalse(coll.findOne(token));
|
||||
Meteor.call("runtimeUniversalSubCreation", token, expect(function (err) {
|
||||
test.isFalse(err);
|
||||
@@ -436,7 +436,7 @@ if (Meteor.isClient) {
|
||||
// conn._subscriptions is empty.
|
||||
var conn = new Meteor._LivedataConnection('/',
|
||||
{reloadWithOutstanding: true});
|
||||
var collName = Meteor.id();
|
||||
var collName = Random.id();
|
||||
var coll = new Meteor.Collection(collName, {manager: conn});
|
||||
var errorFromRerun;
|
||||
var gotErrorFromStopper = false;
|
||||
|
||||
@@ -4,7 +4,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use(['stream', 'uuid']);
|
||||
api.use(['stream', 'random']);
|
||||
api.use(['ejson', 'json', 'underscore', 'deps', 'logging'], ['client', 'server']);
|
||||
|
||||
// livedata_connection.js uses a Minimongo collection internally to
|
||||
|
||||
@@ -375,7 +375,7 @@ LocalCollection.prototype.insert = function (doc) {
|
||||
// if you really want to use ObjectIDs, set this global.
|
||||
// Meteor.Collection specifies its own ids and does not use this code.
|
||||
doc._id = LocalCollection._useOID ? new LocalCollection._ObjectID()
|
||||
: LocalCollection.id();
|
||||
: Random.id();
|
||||
}
|
||||
var id = LocalCollection._idStringify(doc._id);
|
||||
|
||||
|
||||
@@ -1208,7 +1208,7 @@ Tinytest.add("minimongo - observe ordered", function (test) {
|
||||
|
||||
// test stop
|
||||
handle.stop();
|
||||
var idA2 = LocalCollection.id();
|
||||
var idA2 = Random.id();
|
||||
c.insert({_id: idA2, a:2});
|
||||
test.equal(operations.shift(), undefined);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ LocalCollection._ObjectID = function (hexString) {
|
||||
// meant to work with _.isEqual(), which relies on structural equality
|
||||
self._str = hexString;
|
||||
} else {
|
||||
self._str = LocalCollection._randomHexString(24);
|
||||
self._str = Random.hexString(24);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@ Package.on_use(function (api, where) {
|
||||
|
||||
// It would be sort of nice if minimongo didn't depend on
|
||||
// underscore, so we could ship it separately.
|
||||
api.use(['underscore', 'json', 'ejson', 'ordered-dict'], where);
|
||||
api.use(['underscore', 'json', 'ejson', 'ordered-dict', 'random'], where);
|
||||
api.add_files([
|
||||
'minimongo.js',
|
||||
'selector.js',
|
||||
'uuid.js',
|
||||
'modify.js',
|
||||
'diff.js',
|
||||
'objectid.js'
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
// XXX dups packages/uuid/uuid.js
|
||||
|
||||
// LocalCollection.random() -- known good PRNG, replaces Math.random()
|
||||
// LocalCollection.uuid() -- returns RFC 4122 v4 UUID.
|
||||
|
||||
// see http://baagoe.org/en/wiki/Better_random_numbers_for_javascript
|
||||
// for a full discussion and Alea implementation.
|
||||
|
||||
// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
(function() {
|
||||
|
||||
var HEX_DIGITS = "0123456789abcdef";
|
||||
var UNMISTAKABLE_CHARS = "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
LocalCollection._Alea = function () {
|
||||
function Mash() {
|
||||
var n = 0xefc8249d;
|
||||
|
||||
var mash = function(data) {
|
||||
data = data.toString();
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
n += data.charCodeAt(i);
|
||||
var h = 0.02519603282416938 * n;
|
||||
n = h >>> 0;
|
||||
h -= n;
|
||||
h *= n;
|
||||
n = h >>> 0;
|
||||
h -= n;
|
||||
n += h * 0x100000000; // 2^32
|
||||
}
|
||||
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
|
||||
};
|
||||
|
||||
mash.version = 'Mash 0.9';
|
||||
return mash;
|
||||
}
|
||||
|
||||
return (function (args) {
|
||||
var s0 = 0;
|
||||
var s1 = 0;
|
||||
var s2 = 0;
|
||||
var c = 1;
|
||||
|
||||
if (args.length == 0) {
|
||||
args = [+new Date];
|
||||
}
|
||||
var mash = Mash();
|
||||
s0 = mash(' ');
|
||||
s1 = mash(' ');
|
||||
s2 = mash(' ');
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
s0 -= mash(args[i]);
|
||||
if (s0 < 0) {
|
||||
s0 += 1;
|
||||
}
|
||||
s1 -= mash(args[i]);
|
||||
if (s1 < 0) {
|
||||
s1 += 1;
|
||||
}
|
||||
s2 -= mash(args[i]);
|
||||
if (s2 < 0) {
|
||||
s2 += 1;
|
||||
}
|
||||
}
|
||||
mash = null;
|
||||
|
||||
var random = function() {
|
||||
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
|
||||
s0 = s1;
|
||||
s1 = s2;
|
||||
return s2 = t - (c = t | 0);
|
||||
};
|
||||
random.uint32 = function() {
|
||||
return random() * 0x100000000; // 2^32
|
||||
};
|
||||
random.fract53 = function() {
|
||||
return random() +
|
||||
(random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
|
||||
};
|
||||
random.version = 'Alea 0.9';
|
||||
random.args = args;
|
||||
return random;
|
||||
|
||||
} (Array.prototype.slice.call(arguments)));
|
||||
}
|
||||
|
||||
// instantiate RNG. Heuristically collect entropy from various sources
|
||||
|
||||
// client sources
|
||||
var height = (typeof window !== 'undefined' && window.innerHeight) ||
|
||||
(typeof document !== 'undefined'
|
||||
&& document.documentElement
|
||||
&& document.documentElement.clientHeight) ||
|
||||
(typeof document !== 'undefined'
|
||||
&& document.body
|
||||
&& document.body.clientHeight) ||
|
||||
1;
|
||||
|
||||
var width = (typeof window !== 'undefined' && window.innerWidth) ||
|
||||
(typeof document !== 'undefined'
|
||||
&& document.documentElement
|
||||
&& document.documentElement.clientWidth) ||
|
||||
(typeof document !== 'undefined'
|
||||
&& document.body
|
||||
&& document.body.clientWidth) ||
|
||||
1;
|
||||
|
||||
var agent = (typeof navigator !== 'undefined' && navigator.userAgent) || "";
|
||||
|
||||
// server sources
|
||||
var pid = (typeof process !== 'undefined' && process.pid) || 1;
|
||||
|
||||
LocalCollection.random = new LocalCollection._Alea([
|
||||
new Date(), height, width, agent, pid, Math.random()]);
|
||||
|
||||
LocalCollection._randomHexString = function (len) {
|
||||
var digits = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
digits[i] = HEX_DIGITS.substr(Math.floor(LocalCollection.random() * 0x10),
|
||||
1);
|
||||
}
|
||||
return digits.join("");
|
||||
};
|
||||
|
||||
// RFC 4122 v4 UUID.
|
||||
LocalCollection.uuid = function () {
|
||||
var s = [];
|
||||
for (var i = 0; i < 36; i++) {
|
||||
s[i] = HEX_DIGITS.substr(Math.floor(LocalCollection.random() * 0x10), 1);
|
||||
}
|
||||
s[14] = "4";
|
||||
s[19] = HEX_DIGITS.substr((parseInt(s[19],16) & 0x3) | 0x8, 1);
|
||||
s[8] = s[13] = s[18] = s[23] = "-";
|
||||
|
||||
var uuid = s.join("");
|
||||
return uuid;
|
||||
};
|
||||
|
||||
LocalCollection.id = function() {
|
||||
var digits = [];
|
||||
var base = UNMISTAKABLE_CHARS.length;
|
||||
// Length of 17 preserves around 96 bits of entropy, which is the
|
||||
// amount of state in our PRNG
|
||||
for (var i = 0; i < 17; i++) {
|
||||
digits[i] = UNMISTAKABLE_CHARS.substr(Math.floor(LocalCollection.random() * base), 1);
|
||||
}
|
||||
return digits.join("");
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -28,7 +28,7 @@ Meteor.Collection = function (name, options) {
|
||||
case 'STRING':
|
||||
default:
|
||||
self._makeNewID = function () {
|
||||
return LocalCollection.id();
|
||||
return Random.id();
|
||||
};
|
||||
break;
|
||||
}
|
||||
@@ -201,7 +201,7 @@ Meteor.Collection._rewriteSelector = function (selector) {
|
||||
|
||||
if (!selector || (('_id' in selector) && !selector._id))
|
||||
// can't match anything
|
||||
return {_id: LocalCollection.id()};
|
||||
return {_id: Random.id()};
|
||||
|
||||
var ret = {};
|
||||
_.each(selector, function (value, key) {
|
||||
|
||||
@@ -229,8 +229,8 @@ Tinytest.addAsync("mongo-livedata - fuzz test, " + idGeneration, function(test,
|
||||
|
||||
// Use non-deterministic randomness so we can have a shorter fuzz
|
||||
// test (fewer iterations). For deterministic (fully seeded)
|
||||
// randomness, remove the call to Math.random().
|
||||
var seededRandom = new SeededRandom("foobard" + Math.random());
|
||||
// randomness, remove the call to Random.fraction().
|
||||
var seededRandom = new SeededRandom("foobard" + Random.fraction());
|
||||
// Random integer in [0,n)
|
||||
var rnd = function (n) {
|
||||
return seededRandom.nextIntBetween(0, n-1);
|
||||
@@ -545,7 +545,7 @@ if (Meteor.isServer) {
|
||||
|
||||
testAsyncMulti('mongo-livedata - rewrite selector, ' + idGeneration, [
|
||||
function (test, expect) {
|
||||
var collectionName = Meteor.uuid();
|
||||
var collectionName = Random.id();
|
||||
if (Meteor.isClient) {
|
||||
Meteor.call('createInsecureCollection', collectionName, collectionOptions);
|
||||
Meteor.subscribe('c-' + collectionName);
|
||||
@@ -583,7 +583,7 @@ testAsyncMulti('mongo-livedata - rewrite selector, ' + idGeneration, [
|
||||
|
||||
testAsyncMulti('mongo-livedata - empty documents, ' + idGeneration, [
|
||||
function (test, expect) {
|
||||
var collectionName = Meteor.uuid();
|
||||
var collectionName = Random.id();
|
||||
if (Meteor.isClient) {
|
||||
Meteor.call('createInsecureCollection', collectionName);
|
||||
Meteor.subscribe('c-' + collectionName);
|
||||
@@ -604,7 +604,7 @@ testAsyncMulti('mongo-livedata - empty documents, ' + idGeneration, [
|
||||
|
||||
testAsyncMulti('mongo-livedata - document with a date, ' + idGeneration, [
|
||||
function (test, expect) {
|
||||
var collectionName = Meteor.uuid();
|
||||
var collectionName = Random.id();
|
||||
if (Meteor.isClient) {
|
||||
Meteor.call('createInsecureCollection', collectionName, collectionOptions);
|
||||
Meteor.subscribe('c-' + collectionName);
|
||||
@@ -633,7 +633,7 @@ testAsyncMulti('mongo-livedata - document with binary data, ' + idGeneration, [
|
||||
"dCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdl" +
|
||||
"bmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9y" +
|
||||
"dCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
|
||||
var collectionName = Meteor.uuid();
|
||||
var collectionName = Random.id();
|
||||
if (Meteor.isClient) {
|
||||
Meteor.call('createInsecureCollection', collectionName, collectionOptions);
|
||||
Meteor.subscribe('c-' + collectionName);
|
||||
@@ -658,7 +658,7 @@ testAsyncMulti('mongo-livedata - document with binary data, ' + idGeneration, [
|
||||
|
||||
testAsyncMulti('mongo-livedata - specified _id', [
|
||||
function (test, expect) {
|
||||
var collectionName = Meteor.uuid();
|
||||
var collectionName = Random.id();
|
||||
if (Meteor.isClient) {
|
||||
Meteor.call('createInsecureCollection', collectionName);
|
||||
Meteor.subscribe('c-' + collectionName);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
var makeCollection = function () {
|
||||
if (Meteor.isServer)
|
||||
return new Meteor.Collection(Meteor.id());
|
||||
return new Meteor.Collection(Random.id());
|
||||
else
|
||||
return new Meteor.Collection(null);
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use(['uuid', 'ejson', 'json', 'underscore', 'minimongo', 'logging', 'livedata'],
|
||||
api.use(['random', 'ejson', 'json', 'underscore', 'minimongo', 'logging', 'livedata'],
|
||||
['client', 'server']);
|
||||
|
||||
api.add_files('mongo_driver.js', 'server');
|
||||
|
||||
@@ -11,3 +11,19 @@ Meteor.deps.Context.prototype.on_invalidate =
|
||||
// We used to require a special "autosubscribe" call to reactively subscribe to
|
||||
// things. Now, it works with autorun.
|
||||
Meteor.autosubscribe = Meteor.autorun;
|
||||
|
||||
// Instead of the "random" package with Random.id(), we used to have this
|
||||
// Meteor.uuid() implementing the RFC 4122 v4 UUID.
|
||||
Meteor.uuid = function () {
|
||||
var HEX_DIGITS = "0123456789abcdef";
|
||||
var s = [];
|
||||
for (var i = 0; i < 36; i++) {
|
||||
s[i] = Random.choice(HEX_DIGITS);
|
||||
}
|
||||
s[14] = "4";
|
||||
s[19] = HEX_DIGITS.substr((parseInt(s[19],16) & 0x3) | 0x8, 1);
|
||||
s[8] = s[13] = s[18] = s[23] = "-";
|
||||
|
||||
var uuid = s.join("");
|
||||
return uuid;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Package.describe({
|
||||
summary: "Better random number and UUIDv4 generators",
|
||||
summary: "Random number generator and utilities",
|
||||
internal: true
|
||||
});
|
||||
|
||||
Package.on_use(function (api, where) {
|
||||
where = where || ['client', 'server'];
|
||||
api.add_files('uuid.js', where);
|
||||
api.add_files('random.js', where);
|
||||
});
|
||||
@@ -1,38 +1,10 @@
|
||||
// XXX dups packages/minimongo/uuid.js
|
||||
(function() {
|
||||
|
||||
// Meteor.random() -- known good PRNG, replaces Math.random()
|
||||
// Meteor.uuid() -- returns RFC 4122 v4 UUID.
|
||||
Random = {};
|
||||
|
||||
// see http://baagoe.org/en/wiki/Better_random_numbers_for_javascript
|
||||
// for a full discussion and Alea implementation.
|
||||
|
||||
// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
(function() {
|
||||
|
||||
var HEX_DIGITS = "0123456789abcdef";
|
||||
var UNMISTAKABLE_CHARS = "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
var Alea = Meteor._Alea = function () {
|
||||
Random._Alea = function () {
|
||||
function Mash() {
|
||||
var n = 0xefc8249d;
|
||||
|
||||
@@ -103,7 +75,7 @@ var Alea = Meteor._Alea = function () {
|
||||
return random;
|
||||
|
||||
} (Array.prototype.slice.call(arguments)));
|
||||
}
|
||||
};
|
||||
|
||||
// instantiate RNG. Heuristically collect entropy from various sources
|
||||
|
||||
@@ -131,32 +103,38 @@ var agent = (typeof navigator !== 'undefined' && navigator.userAgent) || "";
|
||||
// server sources
|
||||
var pid = (typeof process !== 'undefined' && process.pid) || 1;
|
||||
|
||||
Meteor.random = new Alea([
|
||||
// XXX On the server, use the crypto module (OpenSSL) instead of this PRNG.
|
||||
// (Make Random.fraction be generated from Random.hexString instead of the
|
||||
// other way around, and generate Random.hexString from crypto.randomBytes.)
|
||||
Random.fraction = new Random._Alea([
|
||||
new Date(), height, width, agent, pid, Math.random()]);
|
||||
|
||||
// RFC 4122 v4 UUID.
|
||||
Meteor.uuid = function () {
|
||||
var s = [];
|
||||
for (var i = 0; i < 36; i++) {
|
||||
s[i] = HEX_DIGITS.substr(Math.floor(Meteor.random() * 0x10), 1);
|
||||
}
|
||||
s[14] = "4";
|
||||
s[19] = HEX_DIGITS.substr((parseInt(s[19],16) & 0x3) | 0x8, 1);
|
||||
s[8] = s[13] = s[18] = s[23] = "-";
|
||||
|
||||
var uuid = s.join("");
|
||||
return uuid;
|
||||
Random.choice = function (arrayOrString) {
|
||||
var index = Math.floor(Random.fraction() * arrayOrString.length);
|
||||
if (typeof arrayOrString === "string")
|
||||
return arrayOrString.substr(index, 1);
|
||||
else
|
||||
return arrayOrString[index];
|
||||
};
|
||||
|
||||
Meteor.id = function() {
|
||||
var UNMISTAKABLE_CHARS = "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
Random.id = function() {
|
||||
var digits = [];
|
||||
var base = UNMISTAKABLE_CHARS.length;
|
||||
// Length of 17 preserves around 96 bits of entropy, which is the
|
||||
// amount of state in our PRNG
|
||||
for (var i = 0; i < 17; i++) {
|
||||
digits[i] = UNMISTAKABLE_CHARS.substr(Math.floor(Meteor.random() * base), 1);
|
||||
digits[i] = Random.choice(UNMISTAKABLE_CHARS);
|
||||
}
|
||||
return digits.join("");
|
||||
};
|
||||
|
||||
var HEX_DIGITS = "0123456789abcdef";
|
||||
Random.hexString = function (digits) {
|
||||
var hexDigits = [];
|
||||
for (var i = 0; i < digits; ++i) {
|
||||
hexDigits.push(Random.choice("0123456789abcdef"));
|
||||
}
|
||||
return hexDigits.join('');
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -4,7 +4,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use(['underscore', 'uuid', 'domutils', 'liverange', 'universal-events'],
|
||||
api.use(['underscore', 'random', 'domutils', 'liverange', 'universal-events'],
|
||||
'client');
|
||||
|
||||
api.add_files(['spark.js', 'patch.js', 'convenience.js',
|
||||
|
||||
@@ -44,7 +44,7 @@ Spark._currentRenderer = (function () {
|
||||
};
|
||||
})();
|
||||
|
||||
Spark._TAG = "_spark_" + Meteor.uuid();
|
||||
Spark._TAG = "_spark_" + Random.id();
|
||||
// XXX document contract for each type of annotation?
|
||||
Spark._ANNOTATION_NOTIFY = "notify";
|
||||
Spark._ANNOTATION_DATA = "data";
|
||||
@@ -106,16 +106,6 @@ var withEventGuard = function (func) {
|
||||
finally { eventGuardActive = previous; }
|
||||
};
|
||||
|
||||
Spark._createId = function () {
|
||||
// Chars can't include '-' to be safe inside HTML comments.
|
||||
var chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
|
||||
var id = "";
|
||||
for (var i = 0; i < 8; i++)
|
||||
id += chars.substr(Math.floor(Meteor.random() * 64), 1);
|
||||
return id;
|
||||
};
|
||||
|
||||
Spark._Renderer = function () {
|
||||
// Map from annotation ID to an annotation function, which is called
|
||||
// at render time and receives (startNode, endNode).
|
||||
@@ -164,7 +154,7 @@ _.extend(Spark._Renderer.prototype, {
|
||||
// unescaped < and > in HTML attribute values, where they are normally
|
||||
// safe. We can't assume that a string like '<1>' came from us
|
||||
// and not arbitrary user-entered data.
|
||||
var id = (type || '') + ":" + Spark._createId();
|
||||
var id = (type || '') + ":" + Random.id();
|
||||
this.annotations[id] = function (start, end) {
|
||||
if ((! start) || (! type)) {
|
||||
// ! start: materialize called us with no args because this
|
||||
@@ -1100,7 +1090,7 @@ Spark.labelBranch = function (label, htmlFunc) {
|
||||
return htmlFunc();
|
||||
|
||||
if (label === Spark.UNIQUE_LABEL)
|
||||
label = Spark._createId();
|
||||
label = Random.id();
|
||||
|
||||
renderer.currentBranch.pushLabel(label);
|
||||
var html = htmlFunc();
|
||||
|
||||
@@ -1639,8 +1639,8 @@ Tinytest.add("spark - landmark patching", function(test) {
|
||||
for(var i=0; i<5; i++) {
|
||||
// Use non-deterministic randomness so we can have a shorter fuzz
|
||||
// test (fewer iterations). For deterministic (fully seeded)
|
||||
// randomness, remove the call to Math.random().
|
||||
rand = new SeededRandom("preserved nodes "+i+" "+Math.random());
|
||||
// randomness, remove the call to Random.fraction().
|
||||
rand = new SeededRandom("preserved nodes "+i+" "+Random.fraction());
|
||||
|
||||
var R = ReactiveVar(false);
|
||||
var structure = randomNodeList(null, 6);
|
||||
@@ -1878,7 +1878,7 @@ Tinytest.add("spark - leaderboard, " + idGeneration, function(test) {
|
||||
}));
|
||||
var idGen;
|
||||
if (idGeneration === 'STRING')
|
||||
idGen = LocalCollection.id;
|
||||
idGen = Random.id;
|
||||
else
|
||||
idGen = function () { return new LocalCollection._ObjectID(); };
|
||||
|
||||
@@ -2550,7 +2550,7 @@ testAsyncMulti(
|
||||
// This is quite a tricky implementation.
|
||||
|
||||
var withIframe = function(onReady1, onReady2) {
|
||||
var frameName = "submitframe"+String(Math.random()).slice(2);
|
||||
var frameName = "submitframe"+String(Random.fraction()).slice(2);
|
||||
var iframeDiv = OnscreenDiv(
|
||||
Meteor.render(function() {
|
||||
return '<iframe name="'+frameName+'" '+
|
||||
|
||||
@@ -4,7 +4,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use('uuid', ['client', 'server']);
|
||||
api.use('random', ['client', 'server']);
|
||||
api.add_files(['biginteger.js', 'sha256.js', 'srp.js'],
|
||||
['client', 'server']);
|
||||
});
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
Meteor._srp.generateVerifier = function (password, options) {
|
||||
var params = paramsFromOptions(options);
|
||||
|
||||
var identity = (options && options.identity) || Meteor.uuid();
|
||||
var salt = (options && options.salt) || Meteor.uuid();
|
||||
var identity = (options && options.identity) || Random.id();
|
||||
var salt = (options && options.salt) || Random.id();
|
||||
|
||||
var x = params.hash(salt + params.hash(identity + ":" + password));
|
||||
var xi = new Meteor._srp.BigInteger(x, 16);
|
||||
@@ -332,8 +332,7 @@
|
||||
|
||||
|
||||
var randInt = function () {
|
||||
// XXX XXX need a better implementation!
|
||||
return new Meteor._srp.BigInteger(Meteor.uuid().replace(/-/g, ''), 16);
|
||||
return new Meteor._srp.BigInteger(Random.hexString(36), 16);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use(['underscore', 'logging', 'uuid', 'json'], ['client', 'server']);
|
||||
api.use(['underscore', 'logging', 'random', 'json'], ['client', 'server']);
|
||||
api.use('reload', 'client');
|
||||
|
||||
api.add_files('sockjs-0.3.4.js', 'client');
|
||||
|
||||
@@ -94,7 +94,7 @@ _.extend(Meteor._Stream, {
|
||||
// allows different stream connections to connect to different hostnames
|
||||
// and avoid browser per-hostname connection limits.
|
||||
host = host.replace(/\*/g, function () {
|
||||
return Math.floor(Math.random()*10);
|
||||
return Math.floor(Random.fraction()*10);
|
||||
});
|
||||
|
||||
return newScheme + '://' + host + rest;
|
||||
@@ -296,7 +296,7 @@ _.extend(Meteor._Stream.prototype, {
|
||||
self.RETRY_BASE_TIMEOUT * Math.pow(self.RETRY_EXPONENT, count));
|
||||
// fuzz the timeout randomly, to avoid reconnect storms when a
|
||||
// server goes down.
|
||||
timeout = timeout * ((Math.random() * self.RETRY_FUZZ) +
|
||||
timeout = timeout * ((Random.fraction() * self.RETRY_FUZZ) +
|
||||
(1 - self.RETRY_FUZZ/2));
|
||||
return timeout;
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// custom serverId which you only change when something worth pushing
|
||||
// to clients immediately happens.
|
||||
__meteor_runtime_config__.serverId =
|
||||
process.env.SERVER_ID ? process.env.SERVER_ID : Meteor.uuid();
|
||||
process.env.SERVER_ID ? process.env.SERVER_ID : Random.id();
|
||||
|
||||
Meteor._StreamServer = function () {
|
||||
var self = this;
|
||||
|
||||
@@ -5,7 +5,7 @@ var SeededRandom = function(seed) { // seed may be a string or any type
|
||||
return new SeededRandom(seed);
|
||||
|
||||
seed = seed || "seed";
|
||||
this.gen = new Meteor._Alea(seed); // from uuid.js
|
||||
this.gen = new Random._Alea(seed); // from random.js
|
||||
};
|
||||
SeededRandom.prototype.next = function() {
|
||||
return this.gen();
|
||||
|
||||
@@ -12,7 +12,7 @@ TestCaseResults = function (test_case, onEvent, onException, stop_at_offset) {
|
||||
self.current_fail_count = 0;
|
||||
self.stop_at_offset = stop_at_offset;
|
||||
self.onException = onException;
|
||||
self.id = Meteor.uuid();
|
||||
self.id = Random.id();
|
||||
};
|
||||
|
||||
_.extend(TestCaseResults.prototype, {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// the server. Sets a 'server' flag on test results that came from the
|
||||
// server.
|
||||
Meteor._runTestsEverywhere = function (onReport, onComplete) {
|
||||
var runId = LocalCollection.uuid();
|
||||
var runId = Random.id();
|
||||
var localComplete = false;
|
||||
var remoteComplete = false;
|
||||
var done = false;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"You probably forgot to wrap a callback in bindEnvironment.");
|
||||
console.trace();
|
||||
}
|
||||
var dummyKey = Meteor.uuid();
|
||||
var dummyKey = Random.id();
|
||||
var fields = {};
|
||||
fields[dummyKey] = report;
|
||||
_.each(handlesForRun[runId], function (handle) {
|
||||
|
||||
Reference in New Issue
Block a user