Skip to content

Releases: forio/epicenter-js-libs

Add SAMESITE and SECURE flags to cookies

16 Jun 17:55
Compare
Choose a tag to compare

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

29 Jan 00:58
3d9a85a
Compare
Choose a tag to compare

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

05 Jul 21:23
16c0e48
Compare
Choose a tag to compare

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

17 May 23:08
Compare
Choose a tag to compare

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 from getUserRunStrategy
  • 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

27 Mar 19:36
Compare
Choose a tag to compare

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 by getWorldChannel wasn't working, now does.
  • EPICENTER-3942 Variable service query mutated it's inputs for large GETs. Now properly clones.
  • The onCreate parameter to settingsManager.getUserRunStrategy should've been optional but was actually required. Now is optional for real.
  • Data service added a leading / if a custom baseURL 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!

01 Mar 23:30
Compare
Choose a tag to compare

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

05 Feb 18:02
Compare
Choose a tag to compare

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

04 Oct 05:11
Compare
Choose a tag to compare

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 to unauthorized 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 the ScenarioManager used to pick the last run which was not-saved/trashed as the 'current' run; it now sets a trackingKey called current and uses that instead to pick the current run.

Data Scoping and World Topics

10 Jul 17:26
Compare
Choose a tag to compare

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 and message 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

31 May 15:21
Compare
Choose a tag to compare

Bug Fixes:

  • World Service: getCurrentRunId and newRunForWorld calls were ignoring any files or cinFiles 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 the getDataChannel method of the ChannelManager
  • 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.