Comparing version 0.0.1-1f746c46 to 0.0.1-e610b5ce
@@ -8,3 +8,4 @@ "use strict"; | ||
exports.default = function () { | ||
return (0, _redux.createStore)(_reducer2.default, composeEnhancers((0, _redux.applyMiddleware)((0, _reduxImmutableStateInvariant2.default)(), _gameActionMiddleware2.default, _reduxThunk2.default, _gameMiddleware2.default))); | ||
var composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose; | ||
return (0, _redux.createStore)(_reducer2.default, composeEnhancers((0, _redux.applyMiddleware)((0, _reduxImmutableStateInvariant2.default)(), _gameActionMiddleware2.default, _reduxThunk2.default, _gameMiddleware.gameMiddleware))); | ||
}; | ||
@@ -20,4 +21,2 @@ | ||
var _gameMiddleware2 = _interopRequireDefault(_gameMiddleware); | ||
var _reduxImmutableStateInvariant = require("redux-immutable-state-invariant"); | ||
@@ -36,4 +35,2 @@ | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose; | ||
//# sourceMappingURL=create-store.js.map |
@@ -14,8 +14,4 @@ "use strict"; | ||
exports.default = gameMiddleware; | ||
exports.gameMiddleware = gameMiddleware; | ||
var _signalhub = require("signalhub"); | ||
var _signalhub2 = _interopRequireDefault(_signalhub); | ||
var _game = require("@cardcore/game"); | ||
@@ -25,6 +21,18 @@ | ||
var _stateHasher = require("./state-hasher"); | ||
var _client = require("@cardcore/client"); | ||
var _stateHasher2 = _interopRequireDefault(_stateHasher); | ||
var _util = require("@cardcore/util"); | ||
var _ssbKeys = require("@streamplace/ssb-keys"); | ||
var _ssbKeys2 = _interopRequireDefault(_ssbKeys); | ||
var _jsonStableStringify = require("json-stable-stringify"); | ||
var _jsonStableStringify2 = _interopRequireDefault(_jsonStableStringify); | ||
var _isomorphicFetch = require("isomorphic-fetch"); | ||
var _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
@@ -34,5 +42,4 @@ | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } // import signalhub from "signalhub"; | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
@@ -46,36 +53,15 @@ var REMOTE_ACTION = exports.REMOTE_ACTION = Symbol("REMOTE_ACTION"); | ||
var channelName = document.location.pathname.slice(1); | ||
var hub = (0, _signalhub2.default)("butt-card", [server]); | ||
hub.subscribe(channelName).on("data", function () { | ||
var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(action) { | ||
var me; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
me = store.getState().client.keys; | ||
// const hub = signalhub("butt-card", [server]); | ||
// hub.subscribe(channelName).on("data", async action => { | ||
// const me = store.getState().client.keys; | ||
// if (action._sender === me.id) { | ||
// return; | ||
// } | ||
// action = { | ||
// ...action, | ||
// [REMOTE_ACTION]: true | ||
// }; | ||
// store.dispatch(action); | ||
// }); | ||
if (!(action._sender === me.id)) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 3: | ||
action = Object.assign({}, action, _defineProperty({}, REMOTE_ACTION, true)); | ||
store.dispatch(action); | ||
case 5: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, _this); | ||
})); | ||
return function (_x) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}()); | ||
var promises = new WeakMap(); | ||
@@ -90,29 +76,30 @@ | ||
var runNext = function () { | ||
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { | ||
var action, me, isGameAction, ret, hash, _promises$get, _promises$get2, resolve, nextActions, _nextActions$, playerId, notPlayerId, _action; | ||
var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee() { | ||
var action, me, isGameAction, ret, hash, prev, _next, signedAction, res, _server, _promises$get, _promises$get2, resolve, state, nextActions, _nextActions$, playerId, notPlayerId, _action; | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!running) { | ||
_context2.next = 2; | ||
_context.next = 2; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
return _context.abrupt("return"); | ||
case 2: | ||
if (!(queue.length === 0)) { | ||
_context2.next = 4; | ||
_context.next = 5; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
store.dispatch((0, _client.clientPoll)()); | ||
return _context.abrupt("return"); | ||
case 4: | ||
case 5: | ||
action = queue.shift(); | ||
if (!(!sync && action.type !== gameActions.DESYNC)) { | ||
_context2.next = 8; | ||
_context.next = 9; | ||
break; | ||
@@ -123,46 +110,89 @@ } | ||
running = false; | ||
return _context2.abrupt("return"); | ||
return _context.abrupt("return"); | ||
case 8: | ||
case 9: | ||
running = true; | ||
me = store.getState().client.keys; | ||
isGameAction = !!gameActions[action.type]; | ||
_context2.next = 13; | ||
_context.next = 14; | ||
return next(Object.assign({}, action, { | ||
_me: me && me.id, | ||
_prev: isGameAction ? prevHash : undefined | ||
prev: isGameAction ? prevHash : undefined | ||
})); | ||
case 13: | ||
ret = _context2.sent; | ||
_context2.next = 16; | ||
return (0, _stateHasher2.default)(store.getState().game); | ||
case 14: | ||
ret = _context.sent; | ||
_context.next = 17; | ||
return (0, _util.hashState)(store.getState().game); | ||
case 16: | ||
hash = _context2.sent; | ||
case 17: | ||
hash = _context.sent; | ||
if (action[REMOTE_ACTION]) { | ||
prevHash = hash; | ||
// we just completed a remote action, assert states match | ||
if (sync && hash !== action._hash) { | ||
// very bad and extremely fatal for now - perhaps someday we recover | ||
sync = false; | ||
store.dispatch(gameActions.desync(me.id, store.getState().game)); | ||
if (!action[REMOTE_ACTION]) { | ||
_context.next = 23; | ||
break; | ||
} | ||
prevHash = hash; | ||
// we just completed a remote action, assert states match | ||
if (sync && hash !== action.next) { | ||
// very bad and extremely fatal for now - perhaps someday we recover | ||
sync = false; | ||
store.dispatch(gameActions.desync(me.id, store.getState().game)); | ||
} | ||
_context.next = 38; | ||
break; | ||
case 23: | ||
if (!(gameActions[action.type] && action.type !== gameActions.DESYNC)) { | ||
_context.next = 38; | ||
break; | ||
} | ||
prev = prevHash; | ||
prevHash = hash; | ||
// tell everyone else the action happened and the resulting hash | ||
_next = hash; | ||
signedAction = _ssbKeys2.default.signObj(me, Object.assign({}, action, { | ||
prev: prev, | ||
next: _next | ||
})); | ||
_context.next = 30; | ||
return (0, _isomorphicFetch2.default)("/" + encodeURIComponent(_next), { | ||
method: "POST", | ||
body: (0, _jsonStableStringify2.default)(signedAction), | ||
headers: { | ||
"content-type": "application/json" | ||
} | ||
} else if (gameActions[action.type]) { | ||
prevHash = hash; | ||
// tell everyone else the action happened and the resulting hash | ||
hub.broadcast(channelName, Object.assign({}, action, { | ||
_sender: me.id, | ||
_hash: hash | ||
})); | ||
}); | ||
case 30: | ||
res = _context.sent; | ||
if (!(res.status === 409)) { | ||
_context.next = 38; | ||
break; | ||
} | ||
sync = false; | ||
store.dispatch(gameActions.desync("client", store.getState().game)); | ||
_context.next = 36; | ||
return res.json(); | ||
case 36: | ||
_server = _context.sent; | ||
store.dispatch(gameActions.desync("server", _server.state.game)); | ||
case 38: | ||
_promises$get = promises.get(action), _promises$get2 = _slicedToArray(_promises$get, 1), resolve = _promises$get2[0]; // hack, maybe should reject? | ||
running = false; | ||
nextActions = store.getState().game.nextActions; | ||
state = store.getState(); | ||
nextActions = state.game && state.game.nextActions; | ||
// only dequeue if a game action just happened - client actions don't count | ||
if (!(nextActions.length > 0 && gameActions[action.type])) { | ||
_context2.next = 28; | ||
if (!(nextActions && nextActions.length > 0 && (gameActions[action.type] || action.type === _client.CLIENT_LOAD_STATE))) { | ||
_context.next = 49; | ||
break; | ||
@@ -174,3 +204,3 @@ } | ||
if (gameActions[_action.type]) { | ||
_context2.next = 25; | ||
_context.next = 46; | ||
break; | ||
@@ -181,10 +211,10 @@ } | ||
case 25: | ||
case 46: | ||
if (!(playerId && playerId === me.id || notPlayerId && notPlayerId !== me.id // hack hack hack | ||
)) { | ||
_context2.next = 28; | ||
_context.next = 49; | ||
break; | ||
} | ||
_context2.next = 28; | ||
_context.next = 49; | ||
return store.dispatch(Object.assign({}, _action, { | ||
@@ -196,16 +226,16 @@ _fromQueue: true, | ||
case 28: | ||
case 49: | ||
resolve(ret); | ||
runNext(); | ||
case 30: | ||
case 51: | ||
case "end": | ||
return _context2.stop(); | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee2, _this); | ||
}, _callee, _this); | ||
})); | ||
return function runNext() { | ||
return _ref2.apply(this, arguments); | ||
return _ref.apply(this, arguments); | ||
}; | ||
@@ -212,0 +242,0 @@ }(); |
@@ -40,3 +40,12 @@ "use strict"; | ||
var _reducer = require("./reducer"); | ||
Object.defineProperty(exports, "gameReducer", { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_reducer).default; | ||
} | ||
}); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
//# sourceMappingURL=index.js.map |
@@ -19,2 +19,4 @@ "use strict"; | ||
var _util = require("@cardcore/util"); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
@@ -48,3 +50,2 @@ | ||
var reducers = { client: _client.clientReducer, secret: secret }; | ||
function rootReducer() { | ||
@@ -54,4 +55,15 @@ var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
var startRandoSeed = state.game && state.game.randoSeed; | ||
if (state.game && state.game.randoSeed) { | ||
_util.rando.setSeed(startRandoSeed); | ||
} | ||
var reducers = { client: clientActions.clientReducer, secret: secret }; | ||
// temporary hacky game init logic | ||
if (action.type === clientActions.CLIENT_LOAD_STATE) { | ||
return Object.assign({}, state, { | ||
game: action.gameState | ||
}); | ||
} | ||
// special logic to clean out the queue if we're executing a queued action | ||
if (state && state.game && state.game.nextActions[0] && (action._sender === state.game.nextActions[0].playerId || action._sender !== state.game.nextActions[0].notPlayerId) && // omfg hack | ||
if (state && state.game && state.game.nextActions && state.game.nextActions[0] && (action._sender === state.game.nextActions[0].playerId || action._sender !== state.game.nextActions[0].notPlayerId) && // omfg hack | ||
action.type === state.game.nextActions[0].action.type) { | ||
@@ -126,4 +138,12 @@ state = Object.assign({}, state, { | ||
if (state.game && _util.rando.seed && state.game.randoSeed !== _util.rando.seed) { | ||
state = Object.assign({}, state, { | ||
game: Object.assign({}, state.game, { | ||
randoSeed: _util.rando.seed | ||
}) | ||
}); | ||
} | ||
_util.rando.clearSeed(); | ||
return state; | ||
} | ||
//# sourceMappingURL=reducer.js.map |
{ | ||
"name": "cardcore", | ||
"version": "0.0.1-1f746c46", | ||
"version": "0.0.1-e610b5ce", | ||
"description": "Core functions for cards", | ||
@@ -13,3 +13,6 @@ "main": "dist/index.js", | ||
}, | ||
"gitHead": "1f746c46c9911e36a1e9be89edf6da902e8ff20f" | ||
"dependencies": { | ||
"@streamplace/ssb-keys": "^7.0.16" | ||
}, | ||
"gitHead": "e610b5ce494b91bf26736417e3c8ba011f27ae84" | ||
} |
import { createStore, compose, applyMiddleware } from "redux"; | ||
import gameActionMiddleware from "./game-action-middleware"; | ||
import gameMiddleware from "./game-middleware"; | ||
import { gameMiddleware } from "./game-middleware"; | ||
import invariant from "redux-immutable-state-invariant"; | ||
import reducer from "./reducer"; | ||
import thunk from "redux-thunk"; | ||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | ||
export default function() { | ||
const composeEnhancers = | ||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | ||
return createStore( | ||
@@ -11,0 +12,0 @@ reducer, |
@@ -1,22 +0,26 @@ | ||
import signalhub from "signalhub"; | ||
// import signalhub from "signalhub"; | ||
import * as gameActions from "@cardcore/game"; | ||
import hashState from "./state-hasher"; | ||
import { CLIENT_LOAD_STATE, clientPoll } from "@cardcore/client"; | ||
import { hashState } from "@cardcore/util"; | ||
import ssbKeys from "@streamplace/ssb-keys"; | ||
import stringify from "json-stable-stringify"; | ||
import fetch from "isomorphic-fetch"; | ||
export const REMOTE_ACTION = Symbol("REMOTE_ACTION"); | ||
export default function gameMiddleware(store) { | ||
export function gameMiddleware(store) { | ||
const server = `${document.location.protocol}//${document.location.host}`; | ||
const channelName = document.location.pathname.slice(1); | ||
const hub = signalhub("butt-card", [server]); | ||
hub.subscribe(channelName).on("data", async action => { | ||
const me = store.getState().client.keys; | ||
if (action._sender === me.id) { | ||
return; | ||
} | ||
action = { | ||
...action, | ||
[REMOTE_ACTION]: true | ||
}; | ||
store.dispatch(action); | ||
}); | ||
// const hub = signalhub("butt-card", [server]); | ||
// hub.subscribe(channelName).on("data", async action => { | ||
// const me = store.getState().client.keys; | ||
// if (action._sender === me.id) { | ||
// return; | ||
// } | ||
// action = { | ||
// ...action, | ||
// [REMOTE_ACTION]: true | ||
// }; | ||
// store.dispatch(action); | ||
// }); | ||
@@ -36,2 +40,3 @@ const promises = new WeakMap(); | ||
if (queue.length === 0) { | ||
store.dispatch(clientPoll()); | ||
return; | ||
@@ -51,3 +56,3 @@ } | ||
_me: me && me.id, | ||
_prev: isGameAction ? prevHash : undefined | ||
prev: isGameAction ? prevHash : undefined | ||
}); | ||
@@ -58,3 +63,3 @@ const hash = await hashState(store.getState().game); | ||
// we just completed a remote action, assert states match | ||
if (sync && hash !== action._hash) { | ||
if (sync && hash !== action.next) { | ||
// very bad and extremely fatal for now - perhaps someday we recover | ||
@@ -64,16 +69,39 @@ sync = false; | ||
} | ||
} else if (gameActions[action.type]) { | ||
} else if ( | ||
gameActions[action.type] && | ||
action.type !== gameActions.DESYNC | ||
) { | ||
const prev = prevHash; | ||
prevHash = hash; | ||
// tell everyone else the action happened and the resulting hash | ||
hub.broadcast(channelName, { | ||
const next = hash; | ||
const signedAction = ssbKeys.signObj(me, { | ||
...action, | ||
_sender: me.id, | ||
_hash: hash | ||
prev, | ||
next | ||
}); | ||
const res = await fetch(`/${encodeURIComponent(next)}`, { | ||
method: "POST", | ||
body: stringify(signedAction), | ||
headers: { | ||
"content-type": "application/json" | ||
} | ||
}); | ||
if (res.status === 409) { | ||
sync = false; | ||
store.dispatch(gameActions.desync("client", store.getState().game)); | ||
const server = await res.json(); | ||
store.dispatch(gameActions.desync("server", server.state.game)); | ||
} | ||
} | ||
const [resolve] = promises.get(action); // hack, maybe should reject? | ||
running = false; | ||
const nextActions = store.getState().game.nextActions; | ||
const state = store.getState(); | ||
const nextActions = state.game && state.game.nextActions; | ||
// only dequeue if a game action just happened - client actions don't count | ||
if (nextActions.length > 0 && gameActions[action.type]) { | ||
if ( | ||
nextActions && | ||
nextActions.length > 0 && | ||
(gameActions[action.type] || action.type === CLIENT_LOAD_STATE) | ||
) { | ||
const { playerId, notPlayerId, action } = nextActions[0]; | ||
@@ -80,0 +108,0 @@ if (!gameActions[action.type]) { |
export * from "./game-action-middleware"; | ||
export * from "./game-middleware"; | ||
export { default as createStore } from "./create-store"; | ||
export { default as gameReducer } from "./reducer"; |
import * as gameActions from "@cardcore/game"; | ||
import * as clientActions from "@cardcore/client"; | ||
import { clientReducer as client } from "@cardcore/client"; | ||
import { rando } from "@cardcore/util"; | ||
@@ -31,4 +31,15 @@ // automatically find any reducer functions in the actions file and call them | ||
const reducers = { client, secret }; | ||
export default function rootReducer(state = {}, action) { | ||
let startRandoSeed = state.game && state.game.randoSeed; | ||
if (state.game && state.game.randoSeed) { | ||
rando.setSeed(startRandoSeed); | ||
} | ||
const reducers = { client: clientActions.clientReducer, secret }; | ||
// temporary hacky game init logic | ||
if (action.type === clientActions.CLIENT_LOAD_STATE) { | ||
return { | ||
...state, | ||
game: action.gameState | ||
}; | ||
} | ||
// special logic to clean out the queue if we're executing a queued action | ||
@@ -38,2 +49,3 @@ if ( | ||
state.game && | ||
state.game.nextActions && | ||
state.game.nextActions[0] && | ||
@@ -69,3 +81,13 @@ (action._sender === state.game.nextActions[0].playerId || | ||
if (state.game && rando.seed && state.game.randoSeed !== rando.seed) { | ||
state = { | ||
...state, | ||
game: { | ||
...state.game, | ||
randoSeed: rando.seed | ||
} | ||
}; | ||
} | ||
rando.clearSeed(); | ||
return state; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56280
762
1
18
1
+ Added@streamplace/chloride@2.2.12(transitive)
+ Added@streamplace/private-box@0.2.1(transitive)
+ Added@streamplace/ssb-keys@7.0.21(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedchloride-test@1.2.4(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeded2curve@0.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.1.0(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.1.0(transitive)
+ Addedhas-symbols@1.1.0(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-electron@2.2.2(transitive)
+ Addedisarray@2.0.5(transitive)
+ Addedjson-buffer@2.0.11(transitive)
+ Addedjson-stable-stringify@1.1.1(transitive)
+ Addedjsonify@0.0.1(transitive)
+ Addedlibsodium@0.7.15(transitive)
+ Addedlibsodium-wrappers@0.7.15(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedsha.js@2.4.112.4.5(transitive)
+ Addedsodium-browserify@1.3.0(transitive)
+ Addedsodium-browserify-tweetnacl@0.2.6(transitive)
+ Addedsodium-chloride@1.1.2(transitive)
+ Addedtweetnacl@0.14.51.0.3(transitive)
+ Addedtweetnacl-auth@0.3.1(transitive)