@logux/client
Advanced tools
Comparing version 0.7.0 to 0.8.0
# Change Log | ||
This project adheres to [Semantic Versioning](http://semver.org/). | ||
## 0.8 | ||
* Use Logux Core 0.5 and WebSocket Protocol 3. | ||
* Rename `credentials` option to `token`. | ||
* User ID must be always a string without `:`. | ||
* Token must be a string. | ||
* Add `Client#changeUser()` method. | ||
* Add support for dynamic tokens. | ||
## 0.7 | ||
@@ -5,0 +13,0 @@ * Add ES modules support. |
import { Unsubscribe } from 'nanoevents' | ||
import { | ||
Connection, Store, TestTime, Log, ClientNode, Action, Meta, ID | ||
Connection, Store, TestTime, Log, ClientNode, Action, Meta, TokenGenerator | ||
} from '@logux/core' | ||
@@ -42,5 +42,5 @@ | ||
/** | ||
* User ID. Pass `false` if no user. | ||
* User ID. | ||
*/ | ||
userId: string | false | ||
userId: string | ||
@@ -50,3 +50,3 @@ /** | ||
*/ | ||
credentials?: string | ||
token?: string | TokenGenerator | ||
@@ -114,3 +114,3 @@ /** | ||
* | ||
* const app = new Client({ | ||
* const client = new Client({ | ||
* credentials: token, | ||
@@ -121,3 +121,3 @@ * subprotocol: '1.0.0', | ||
* }) | ||
* app.start() | ||
* client.start() | ||
* ``` | ||
@@ -135,3 +135,3 @@ */ | ||
* ```js | ||
* console.log('Connecting to ' + app.options.server) | ||
* console.log('Connecting to ' + client.options.server) | ||
* ```` | ||
@@ -150,3 +150,3 @@ */ | ||
* ```js | ||
* app.log.add(action, { tab: app.tabId }) | ||
* client.log.add(action, { tab: client.tabId }) | ||
* ``` | ||
@@ -160,3 +160,3 @@ */ | ||
* ```js | ||
* console.log('Client ID: ', app.nodeId) | ||
* console.log('Client ID: ', client.nodeId) | ||
* ``` | ||
@@ -170,3 +170,3 @@ */ | ||
* ```js | ||
* app.log.add(action) | ||
* client.log.add(action) | ||
* ``` | ||
@@ -189,3 +189,3 @@ */ | ||
* ```js | ||
* app.start() | ||
* client.start() | ||
* ``` | ||
@@ -204,3 +204,3 @@ */ | ||
* ```js | ||
* app.on('add', (action, meta) => { | ||
* client.on('add', (action, meta) => { | ||
* dispatch(action) | ||
@@ -219,2 +219,20 @@ * }) | ||
/** | ||
* Disconnect from the server, update user, and connect again | ||
* with new credentials. | ||
* | ||
* ```js | ||
* onAuth(async (userId, token) => { | ||
* showLoader() | ||
* client.changeUser(userId, token) | ||
* await client.waitFor('synchronized') | ||
* hideLoader() | ||
* }) | ||
* ``` | ||
* | ||
* @param userId The new user ID. | ||
* @param token Credentials for new user. | ||
*/ | ||
changeUser (userId: string, token: string): void | ||
/** | ||
* Disconnect and stop synchronization. | ||
@@ -224,3 +242,3 @@ * | ||
* shutdown.addEventListener('click', () => { | ||
* app.destroy() | ||
* client.destroy() | ||
* }) | ||
@@ -236,3 +254,3 @@ * ``` | ||
* signout.addEventListener('click', () => { | ||
* app.clean() | ||
* client.clean() | ||
* }) | ||
@@ -239,0 +257,0 @@ * ``` |
@@ -10,2 +10,4 @@ import { createNanoEvents } from 'nanoevents' | ||
let ALLOWED_META = ['id', 'time', 'channels'] | ||
function tabPing (c) { | ||
@@ -23,4 +25,2 @@ localStorage.setItem(c.options.prefix + ':tab:' + c.tabId, Date.now()) | ||
let ALLOWED_META = ['id', 'time', 'channels'] | ||
class Client { | ||
@@ -41,2 +41,11 @@ constructor (opts = { }) { | ||
} | ||
if (this.options.userId === false) { | ||
throw new Error('Replace userId: false to userId: "false"') | ||
} | ||
if (typeof this.options.userId !== 'string') { | ||
throw new Error('userId must be a string') | ||
} | ||
if (this.options.userId.includes(':')) { | ||
throw new Error('userId can’t contain colon character') | ||
} | ||
} | ||
@@ -58,8 +67,2 @@ | ||
if (this.options.userId) { | ||
this.options.userId = this.options.userId.toString() | ||
} else { | ||
this.options.userId = 'false' | ||
} | ||
if (!this.options.time) { | ||
@@ -77,4 +80,4 @@ this.clientId = this.options.userId + ':' + this.getClientId() | ||
if (/^ws:\/\//.test(this.options.server) && !opts.allowDangerousProtocol) { | ||
auth = async cred => { | ||
if (typeof cred !== 'object' || cred.env !== 'development') { | ||
auth = async (nodeId, env) => { | ||
if (env !== 'development') { | ||
console.error( | ||
@@ -199,4 +202,3 @@ 'Without SSL, old proxies block WebSockets. ' + | ||
let outFilter = async (action, meta) => { | ||
let user = meta.id.split(' ')[1].replace(/:.*$/, '') | ||
return !!meta.sync && user === this.options.userId | ||
return !!meta.sync && meta.id.includes(` ${ this.options.userId }:`) | ||
} | ||
@@ -218,3 +220,2 @@ | ||
this.node = new ClientNode(this.nodeId, this.log, connection, { | ||
credentials: this.options.credentials, | ||
subprotocol: this.options.subprotocol, | ||
@@ -224,2 +225,3 @@ outFilter, | ||
outMap, | ||
token: this.options.token, | ||
ping: this.options.ping, | ||
@@ -268,2 +270,31 @@ auth | ||
changeUser (userId, token) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (typeof userId !== 'string') { | ||
throw new Error('userId must be a string') | ||
} | ||
if (userId.includes(':')) { | ||
throw new Error('userId can’t contain colon character') | ||
} | ||
} | ||
let wasConnected = this.node.connected | ||
if (wasConnected) this.node.connection.disconnect('freeze') | ||
this.options.userId = userId | ||
this.options.token = token | ||
this.clientId = userId + this.clientId.split(':')[1] | ||
this.nodeId = this.clientId + ':' + this.tabId | ||
let events = this.node.emitter.events | ||
this.node.connection.emitter.events = { } | ||
this.node = new ClientNode(this.nodeId, this.log, this.node.connection, { | ||
...this.node.options, | ||
token: this.options.token | ||
}) | ||
this.node.emitter.events = events | ||
if (wasConnected) this.node.connection.connect() | ||
} | ||
destroy () { | ||
@@ -270,0 +301,0 @@ this.onUnload() |
@@ -18,6 +18,6 @@ import { Unsubscribe } from 'nanoevents' | ||
* const client = new CrossTabClient({ | ||
* credentials: token.content, | ||
* subprotocol: '1.0.0', | ||
* server: 'wss://example.com:1337', | ||
* userId: userId | ||
* userId, | ||
* token | ||
* }) | ||
@@ -34,4 +34,4 @@ * client.start() | ||
* ```js | ||
* app.on('role', () => { | ||
* console.log('Tab role:', app.role) | ||
* client.on('role', () => { | ||
* console.log('Tab role:', client.role) | ||
* }) | ||
@@ -72,3 +72,3 @@ * ``` | ||
* ```js | ||
* app.on('add', (action, meta) => { | ||
* client.on('add', (action, meta) => { | ||
* dispatch(action) | ||
@@ -75,0 +75,0 @@ * }) |
{ | ||
"name": "@logux/client", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"description": "Logux base components to build web client", | ||
@@ -21,3 +21,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@logux/core": "^0.4.0", | ||
"@logux/core": "^0.5.1", | ||
"browser-supports-log-styles": "^1.1.7", | ||
@@ -24,0 +24,0 @@ "nanoevents": "^5.1.5", |
@@ -50,9 +50,9 @@ # Logux Client [![Cult Of Martians][cult-img]][cult] | ||
let userId = document.querySelector('meta[name=user]').content | ||
let userToken = document.querySelector('meta[name=token]').content | ||
let token = document.querySelector('meta[name=token]').content | ||
const client = new CrossTabClient({ | ||
credentials: userToken, | ||
subprotocol: '1.0.0', | ||
server: 'wss://example.com:1337', | ||
userId: userToken | ||
userId, | ||
token | ||
}) | ||
@@ -59,0 +59,0 @@ |
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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
105805
3191
0
7
+ Added@logux/core@0.5.3(transitive)
- Removed@logux/core@0.4.2(transitive)
Updated@logux/core@^0.5.1