Releases: forio/epicenter-js-libs
Add SAMESITE and SECURE flags to cookies
2.13.0
Improvements: Cookie manager has been improved to be in accordance with modern browser expectations.
- Cookies are set with Secure: true setting if application loaded under https.
- Cookies now allow calling code to set SameSite property.
Run Strategy handles trashed runs
2.12.0
Improvements
- Run strategies now account for runs that are "deleted" ( trashed: true ) runs and return / create a new run based on their default behavior:
- Reuse across sessions: Creates new run if the latest run is trashed
- Reuse by tracking key: Creates new run if the latest run is trashed
- Reuse last initalized: Returns the latest non-trashed run or created a new run if there is no non-trashed run
- Reuse per session: Creates a new run if the run is trashed
Multi-factor authentication
2.11.0
Features
login.js now supports multifactor authentication. See src/components/login/index.html for the necessary HTML components that must be on the login page.
Multiplayer Settings Strategy & more
Features
- Added a
keepOnline
flag to Presence Service.
var pr = new F.service.Presence();
pr.markOnline('0000015a68d806bc09cd0a7d207f44ba5f74', { keepOnline: true });
This will register your presence with the server every 5 minutes. Use cancelKeepOnline
to stop doing so.
- Added sensitivity helper method to State Service (only applicable to Vensim)
- Added Multiplayer support to the Settings Manager. Pass in
multiplayer: true
to the constructor, and you'll now get a multiplayer settings strategy fromgetUserRunStrategy
reuse-by-tracking-key
is now more efficient; only does network call to get run count if you explicitly have a run limit set in your settings.
Bug-fixes
- Multiplayer strategy was still mixing up world-id and run-id in some cases.
- Scenario/RunManager were not correctly passing through the
server
config option, so if you wanted to run the scenario manager against a different server it would not work. It now correctly passes through relevant options to intermediate services.
Improvements
- Generated docs for Time Service
- Each run from tracking-key strategy now returns the associated settings as an object on the run. i.e., you can access
run.settings
to access to the settings that run was created with.
Bug fixes
Bug-fixes
- The multiplayer strategy reset function was sometimes using the wrong run id. This may have been a regression in
2.9.0
, and so All multiplayer simulations should use 2.9.1 instead. - Listening to
TOPICS.RUN_RESET
on the channel instance returned bygetWorldChannel
wasn't working, now does. - EPICENTER-3942 Variable service
query
mutated it's inputs for large GETs. Now properly clones. - The
onCreate
parameter tosettingsManager.getUserRunStrategy
should've been optional but was actually required. Now is optional for real. - Data service added a leading
/
if a custombaseURL
was set while using an API proxy, now uses the correct path.
Improvements
- Removed
objectAssign
polyfill, which was only used in the AuthManager. This is replaced with$.extend
which is what the rest of the code uses anyway, and makes the file-size slightly smaller.
Features
- Though technically a bug-fix release, this release also adds a
rewind
operation to the State service.
Settings and more!
Features
AssetService has a new getTargetUploadURL
method
The new method provides a URL to an Amazon S3 endpoint to which you can upload directly, thereby skipping the middleman (Epicenter). This also allows you to set a expiration data on the asset beyond which it can no longer be accessed.
New 'use-specific-run' strategy
This is useful if you already know the id of the run you want the run-manager to return. This is typically used for impersonation.
Example:
var runOptions = window.location.search.indexOf('impersonate') === -1 ? 'reuse-across-sessions': {
strategy: 'use-specific-run',
strategyOptions: {
runId: 'runidToImpersonate' //usually passed on in the url
}
}
var rs = new F.Manager.Run(runOptions);
SavedRunsManager#getRuns
now follows pages and passes partial results to onData
The Epicenter APIs typically limit to providing 100 records (runs) at a time. You can explicitly as for more but the longer the dataset the slower the performance, and sometimes you may just forget to account for more than 100 runs when you make the call.
getRuns
now follows pages and returns all the runs when it resolves. It fetches runs 100 at a time (controllable by a recordsPerFetch
parameter), and provides progressive partial data if you pass in an onData
parameter.
Example
var sm = new F.manager.SavedRunsManager({ run: ..});
sm.getRuns(['Price', 'OtherVariable'], { saved: true }, { sort: 'desc' }, {
recordsPerFetch: 50,
onData: (partialRuns)=> { //will be called with 50 runs at a time }
}).then((allRuns)=> { //Will be resolved with *all* runs, regardless of however many there are. Pass in `endRecord` if you do want to limit it. })
New SettingsManager
The Settings Manager is designed for controlling in-game settings - which can be model variables, or text descriptions, or any combination - within a group, for authenticated turn-by-turn projects.
See (Documentation)[https://forio.com/epicenter/docs/public/api_adapters/generated/settings-manager/] for more.
Improvements
RunManager now synchronizes (and warns about) parallel getRun
calls.
e.g
var rm = new F.Manager.RunManager({
strategy: 'reuse-never'
});
var prom1 = rm.getRun();
var prom2 = rm.getRun();
//prom1 === prom2, and only 1 run will be created.
To explicitly create 2 runs, use 2 different run manager instances, or chain your getRun
calls.
RunManager Strategies are now exposed as constants
new RunManager({ strategy: 'reuse-never' });
can now be written as
new RunManager({ strategy: RunManager.STRATEGY.REUSE_NEVER })
This helps prevent typos / provides better editor auto-complete.
DataService allows passing in a custom user id for user scoped data
This is useful if you need to read user-scoped data as a facilitator user.
var ds = new F.service.Data({
root: 'scores',
scope: F.service.Data.SCOPES.USER
});
ds.load('firstScore', {}, { userId: 'customUserid' })
RunService#save allows passing in scope
as an object
In previous versions, to update, say the tracking for a run, you'd need to do
rs.save({ 'scope.trackingKey': 'foo' });
This release allows you to express that more idiomatically as:
rs.save({ scope: { trackingKey: 'foo' }});
Strategies can now specify if the run-manager should set a cookie,
Custom strategies can expose a static boolean allowRunIDCache
property to control if the run manager should persist the result from getRun
in a cookie. As a result, the 'reuse-never' strategy no longer sets a (redundant) cookie since it will always create a new run anyway.
Assignment component (Used by the manager and Interface Builder) has been updated to work with Lodash 4
Bug-fixes
- DataService#remove allows providing an array of document ids to remove them all with a single call.
- WorldService#update alllows you to update the World name
- The URL service (which is used by all other services) now has safer defaults when working with non-https urls.
Firefox login hot-fix
This release addresses an issue where users were unable to login with Firefox 65.0.
The root cause was that epjs was inadvertently passing in "password" to $.ajax
which jquery in turn passed to xhr.open
. The signature for xhr.open is XMLHttpRequest.open(method, url, async, user, password)
- passing in a password without an user should be a no-open according the W3C spec but Firefox 65.0 caused it to fail without making the network call.
v2.8.0
Features
Share connections with the Channel Manager
- Different instances of the Channel Manager now use the same underlying websocket connection by default. This should drastically reduce network traffic if you were creating different instances to listen on different channels before. You can replicate the older behavior by setting the 'shareConnection' property to
false
when creating the Channel Manager. e.g.
var cm = new F.manager.ChannelManager({
shareConnection: false
});
New 'consensus' topics for the World Channel
You can now subscribe only to consensus updates on the world channel. e.g.
var worldChannel = cm.getWorldChannel(worldObject);
worldChannel.subscribe(worldChannel.TOPICS.CONSENSUS, function (data) {
console.log(data);
});
Scenario Manager changes
Control scope for baseline run in the Scenario Manager
The baseline
strategy for the scenario manager used to create a new baseline run per user by default. You can now pass in strategy options to control this behavior, and create one for the group instead.
var sm = new F.manager.ScenarioManager({
run: {
model: 'mymodel.vmf'
},
baseline: {
scope: {
scopeByUser: false
}
}
});
Control filters for the saved runs manager
The saved runs manager filters for saved runs by default; you can overrided that by passing in saved: undefined
as a filter. e.g.
var sm = new F.manager.SavedRunsManager({
saved: undefined,
run: runParams
});
sm.getRuns(['Time'], {
saved: undefined,
});
User Management features:
New User Manager (F.manager.User)
This release includes a new 'User Manager' to help facilitate common user management issues (bulk upload users from a textarea for instance).
var UserManager = F.manager.User;
var um = new UserManager(getRunParams());
um.uploadUsersToGroup($('#userTextarea').val()).then(function(){ alert('Upload sucess!'); }).catch(function (res) {
if (res.type === UserManager.errors.EMPTY_USERS) {
alert('No users specified to upload');
} else if (res.type === UserManager.errors.NO_GROUP_PROVIDED) {
alert('No group found. Create a group and login as a facilitator to upload users');
} else {
alert('Unknown error, please try again');
}
});
User service has a new createUsers
function to add users to your account.
var ua = new F.service.User({
account: 'acme-simulations',
});
ua.createUsers([{ userName: '[email protected]', firstName: 'John', lastName: 'Smith', password: 'passw0rd' }]);
Member service has a new addUsersToGroup
to add existing users into a group.
const ma = new F.service.Member();
ma.addUsersToGroup(['42836d4b-5b61-4fe4-80eb-3136e956ee5c', '42836d4b-5b61-4fe4-80eb-3136e956ee5c'])
Improvements:
- Renamed
un_authorized
tounauthorized
in errors thrown by misc. services (Run Manager and Auth Manager) for consistency. - The older lua based run api used to return
{}
instead of[]
for empty results, and jslibs was translating{}
to[]
for consistency. The newer Java-based run api does not have this issue, so this workaround has been removed. - The
current
run strategy for theScenarioManager
used to pick the last run which was not-saved/trashed as the 'current' run; it now sets a trackingKey calledcurrent
and uses that instead to pick the current run.
Data Scoping and World Topics
Features
Epicenter Channel Manager (F.manager.ChannelManager)
getWorldChannel: World Channel allows you to choose topics to subscribe to
You can now subscribe for specific "topics" on the World Channel. For e.g.
const cm = new F.manager.ChannelManager();
const worldChannel = cm.getWorldChannel();
cm.subscribe(worldChannel.TOPICS.RUN, (data, meta)=> {
//Gets all operations/variables/run reset notifications
});
The list of available topics are:
Topic | Description |
---|---|
ALL | All events |
RUN | All Run events |
RUN_VARIABLES | Variable sets only |
RUN_OPERATIONS | Operation executions only |
RUN_RESET | New run attached to the world |
PRESENCE | All Presence events |
PRESENCE_ONLINE | Online notifications only |
PRESENCE_OFFLINE | Offline notifications only |
ROLES | All role events |
ROLES_ASSIGN | Role assignments only |
ROLES_UNASSIGN | Role unassignments |
getWorldChannel: Subscribing to the PRESENCE
topic bootstraps info
Earlier the presence channel used to notify you of presence changes but you still needed to 'bootstrap' initial data for your current users in advance. Now the channel automatically queries for the status of the current users in the world and send it over. For e.g.
Example: Your world has users A,B, and C, out of who A&B are currently online.
const worldChannel = cm.getWorldChannel();
cm.subscribe(worldChannel.TOPICS.PRESENCE, (data, meta)=> {
//Will be called once for A, and once for B, as well as once for every future change to status of A,B, or C
});
Data API Scoping
const DataService = F.service.Data;
const groupScopeDataService = new DataService({
root: 'some-name',
scope: DataService.SCOPES.GROUP,
});
const userScopeDataService = new DataService({
root: 'some-name',
scope: DataService.SCOPES.USER,
});
Available scopes are:
Scope | Readable By | Writable By |
---|---|---|
GROUP | Facilitators & Users in that group | Faciliators in that group |
USER | Faciliator in that group. User who created the collection | Faciliator in that group. User who created the collection |
FACILITATOR | Faciliators in that group | Faciliators in that group |
PROJECT | Any user in the project | Any user in the project |
CUSTOM (default, to opt out of naming conventions) | customize with Epicenter-api-proxy | customize with Epicenter-api-proxy |
Presence API: New method getStatusForUsers
This is similar to getStatus
, except it takes in a whitelist of users to get presence for.
var pr = new F.service.Presence();
pr.getStatusForUsers([{ userId: 'a', userId: 'b'}]).then(function(onlineUsers) {
console.log(onlineUsers[a].isOnline);
});
PasswordService
The new password service allows you to reset user passwords.
var ps = new F.service.Password();
ps.resetPassword('[email protected]', {
subject: 'Please reset your password'
});
Misc
- Promise rejection error message formats have been normalized to always have a
type
andmessage
where possible. - Added
normalizeSlashes
utils to remove invalid slashes in url strings
Bug Fixes:
- Ajax Transport: Fixed bug which prepended username to url when logging in over http
Consensus Service
Bug Fixes:
- World Service:
getCurrentRunId
andnewRunForWorld
calls were ignoring anyfiles
orcinFiles
parameters passed in; they now correctly pass it through to the APIs, facilitating building multiplayer Vensim models relying on external files. - Fixed bug where the muliplayer strategy was prematurely returning a success before a run was actually created.
Improvements:
- If you're using
ngrok
for testing your simulation locally, it is now identified as "local" (and defaults to using api.forio.com)
Features:
New DataService methods:
getChannel
: returns a subscribable hook to the push channel. This is a convenience wrapper around thegetDataChannel
method of theChannelManager
pushToArray
: Adds items to an underlying array structure on a document. See REST API docs for details.
New Consensus Services
Two new (related) services have been added: F.service.Consensus
and F.service.ConsensusGroup
, as well as a helper worldservice.consensus()
method.
The Consensus Service allows you to build common features in multiplayer games like:
- Delaying execution of an operation until all users within a world have 'submitted'
- Enforcing timed 'rounds' within the game
- Providing the model with default values for users who haven't submitted
See documentation for Consensus Service and Consensus Group for more details.
Chores:
- The build process has been switched from browserify to webpack. This should have no visible difference except a slightly smaller bundle size.
- Now that ES6 usage is more common, parts of the codebase has been converted to ES6 and transpiled with Babel.