Base methods for synchronization nodes. Client and server nodes
are based on this module.
Parameter | Type | Description |
---|
nodeId | string | Unique current machine name. |
log | L | Logux log instance to be synchronized. |
connection | Connection | Connection to remote node. |
options ? | NodeOptions<H> | Synchronization options. |
Did we finish remote node authentication.
Type: boolean
.
Is synchronization in process.
node.on('disconnect', () => {
node.connected
})
Type: boolean
.
Connection used to communicate to remote node.
Type: Connection
.
Promise for node data initial loadiging.
Type: Promise<void>
.
Latest remote node’s log added
time, which was successfully
synchronized. It will be saves in log store.
Type: number
.
Latest current log added
time, which was successfully synchronized.
It will be saves in log store.
Type: number
.
Unique current machine name.
console.log(node.localNodeId + ' is started')
Type: string
.
Used Logux protocol.
if (tool.node.localProtocol !== 1) {
throw new Error('Unsupported Logux protocol')
}
Type: number
.
Log for synchronization.
Type: L
.
Minimum version of Logux protocol, which is supported.
console.log(`You need Logux protocol ${node.minProtocol} or higher`)
Type: number
.
Headers set by remote node.
By default, it is an empty object.
let message = I18N_ERRORS[node.remoteHeaders.language || 'en']
node.log.add({ type: 'error', message })
Type: H | EmptyHeaders
.
Unique name of remote machine.
It is undefined until nodes handshake.
console.log('Connected to ' + node.remoteNodeId)
Type: string | undefined
.
Remote node Logux protocol.
It is undefined until nodes handshake.
if (node.remoteProtocol >= 5) {
useNewAPI()
} else {
useOldAPI()
}
Type: number | undefined
.
Remote node’s application subprotocol version in SemVer format.
It is undefined until nodes handshake. If remote node will not send
on handshake its subprotocol, it will be set to 0.0.0
.
if (semver.satisfies(node.remoteSubprotocol, '>= 5.0.0') {
useNewAPI()
} else {
useOldAPI()
}
Type: string | undefined
.
Current synchronization state.
disconnected
: no connection.
connecting
: connection was started and we wait for node answer.
sending
: new actions was sent, waiting for answer.
synchronized
: all actions was synchronized and we keep connection.
node.on('state', () => {
if (node.state === 'sending') {
console.log('Do not close browser')
}
})
Type: 'disconnected' | 'connecting' | 'sending' | 'synchronized'
.
Time difference between nodes.
Type: number
.
Disable throwing a error on error message and create error listener.
node.catch(error => {
console.error(error)
})
Parameter | Type | Description |
---|
listener | (error: LoguxError) => void | The error listener. |
Returns Unsubscribe
. Unbind listener from event.
Shut down the connection and unsubscribe from log events.
connection.on('disconnect', () => {
server.destroy()
})
Subscribe for synchronization events. It implements nanoevents API.
Supported events:
state
: synchronization state was changed.
connect
: custom check before node authentication. You can throw
a LoguxError
to send error to remote node.
error
: synchronization error was raised.
clientError
: when error was sent to remote node.
debug
: when debug information received from remote node.
headers
: headers was receive from remote node.
node.on('clientError', error => {
logError(error)
})
Parameter | Type | Description |
---|
event | 'state' | 'connect' | 'debug' | 'headers' | Event name. |
listener | () => void | The listener function. |
Parameter | Type |
---|
event | 'error' | 'clientError' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'debug' |
listener | (type: 'error', data: string) => void |
Parameter | Type |
---|
event | 'headers' |
listener | (headers: H) => void |
Returns Unsubscribe
. Unbind listener from event.
Set headers for current node.
if (navigator) {
node.setLocalHeaders({ language: navigator.language })
}
node.connection.connect()
Parameter | Type | Description |
---|
headers | object | The data object will be set as headers for current node. |
Return Promise until sync will have specific state.
If current state is correct, method will return resolved Promise.
await node.waitFor('synchronized')
console.log('Everything is synchronized')
Parameter | Type | Description |
---|
state | 'disconnected' | 'connecting' | 'sending' | 'synchronized' | The expected synchronization state value. |
Returns Promise<void>
. Promise until specific state.
Base class for browser API to be extended in CrossTabClient
.
Because this class could have conflicts between different browser tab,
you should use it only if you are really sure, that application will not
be run in different tab (for instance, if you are developing a kiosk app).
import { Client } from '@logux/client'
const userId = document.querySelector('meta[name=user]').content
const token = document.querySelector('meta[name=token]').content
const client = new Client({
credentials: token,
subprotocol: '1.0.0',
server: 'wss://example.com:1337',
userId: userId
})
client.start()
Unique permanent client ID. Can be used to track this machine.
Type: string
.
Client events log.
client.log.add(action)
Type: L
.
Node instance to synchronize logs.
if (client.node.state === 'synchronized')
Type: ClientNode<H, L>
.
Unique Logux node ID.
console.log('Client ID: ', client.nodeId)
Type: string
.
Client options.
console.log('Connecting to ' + client.options.server)
Type: ClientOptions
.
Unique tab ID. Can be used to add an action to the specific tab.
client.log.add(action, { tab: client.tabId })
Type: TabID
.
Disconnect from the server, update user, and connect again
with new credentials.
onAuth(async (userId, token) => {
showLoader()
client.changeUser(userId, token)
await client.node.waitFor('synchronized')
hideLoader()
})
You need manually chang user ID in all browser tabs.
Parameter | Type | Description |
---|
userId | string | The new user ID. |
token ? | string | Credentials for new user. |
Clear stored data. Removes action log from IndexedDB
if you used it.
signout.addEventListener('click', () => {
client.clean()
})
Returns Promise<void>
. Promise when all data will be removed.
Disconnect and stop synchronization.
shutdown.addEventListener('click', () => {
client.destroy()
})
Subscribe for synchronization events. It implements Nano Events API.
Supported events:
preadd
: action is going to be added (in current tab).
add
: action has been added to log (by any tab).
clean
: action has been removed from log (by any tab).
user
: user ID was changed.
client.on('add', (action, meta) => {
dispatch(action)
})
Parameter | Type | Description |
---|
event | 'preadd' | 'add' | 'clean' | The event name. |
listener | ClientActionListener | The listener function. |
Parameter | Type |
---|
event | 'user' |
listener | (userId: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Connect to server and reconnect on any connection problem.
client.start()
Extends BaseNode.
Client node in synchronization pair.
Instead of server node, it initializes synchronization
and sends connect message.
import { ClientNode } from '@logux/core'
const connection = new BrowserConnection(url)
const node = new ClientNode(nodeId, log, connection)
Parameter | Type | Description |
---|
nodeId | string | Unique current machine name. |
log | L | Logux log instance to be synchronized. |
connection | Connection | Connection to remote node. |
options ? | NodeOptions<H> | Synchronization options. |
Did we finish remote node authentication.
Type: boolean
.
Is synchronization in process.
node.on('disconnect', () => {
node.connected
})
Type: boolean
.
Connection used to communicate to remote node.
Type: Connection
.
Promise for node data initial loadiging.
Type: Promise<void>
.
Latest remote node’s log added
time, which was successfully
synchronized. It will be saves in log store.
Type: number
.
Latest current log added
time, which was successfully synchronized.
It will be saves in log store.
Type: number
.
Unique current machine name.
console.log(node.localNodeId + ' is started')
Type: string
.
Used Logux protocol.
if (tool.node.localProtocol !== 1) {
throw new Error('Unsupported Logux protocol')
}
Type: number
.
Log for synchronization.
Type: L
.
Minimum version of Logux protocol, which is supported.
console.log(`You need Logux protocol ${node.minProtocol} or higher`)
Type: number
.
Headers set by remote node.
By default, it is an empty object.
let message = I18N_ERRORS[node.remoteHeaders.language || 'en']
node.log.add({ type: 'error', message })
Type: H | EmptyHeaders
.
Unique name of remote machine.
It is undefined until nodes handshake.
console.log('Connected to ' + node.remoteNodeId)
Type: string | undefined
.
Remote node Logux protocol.
It is undefined until nodes handshake.
if (node.remoteProtocol >= 5) {
useNewAPI()
} else {
useOldAPI()
}
Type: number | undefined
.
Remote node’s application subprotocol version in SemVer format.
It is undefined until nodes handshake. If remote node will not send
on handshake its subprotocol, it will be set to 0.0.0
.
if (semver.satisfies(node.remoteSubprotocol, '>= 5.0.0') {
useNewAPI()
} else {
useOldAPI()
}
Type: string | undefined
.
Current synchronization state.
disconnected
: no connection.
connecting
: connection was started and we wait for node answer.
sending
: new actions was sent, waiting for answer.
synchronized
: all actions was synchronized and we keep connection.
node.on('state', () => {
if (node.state === 'sending') {
console.log('Do not close browser')
}
})
Type: 'disconnected' | 'connecting' | 'sending' | 'synchronized'
.
Time difference between nodes.
Type: number
.
Disable throwing a error on error message and create error listener.
node.catch(error => {
console.error(error)
})
Parameter | Type | Description |
---|
listener | (error: LoguxError) => void | The error listener. |
Returns Unsubscribe
. Unbind listener from event.
Shut down the connection and unsubscribe from log events.
connection.on('disconnect', () => {
server.destroy()
})
Subscribe for synchronization events. It implements nanoevents API.
Supported events:
state
: synchronization state was changed.
connect
: custom check before node authentication. You can throw
a LoguxError
to send error to remote node.
error
: synchronization error was raised.
clientError
: when error was sent to remote node.
debug
: when debug information received from remote node.
headers
: headers was receive from remote node.
node.on('clientError', error => {
logError(error)
})
Parameter | Type | Description |
---|
event | 'state' | 'connect' | 'debug' | 'headers' | Event name. |
listener | () => void | The listener function. |
Parameter | Type |
---|
event | 'error' | 'clientError' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'debug' |
listener | (type: 'error', data: string) => void |
Parameter | Type |
---|
event | 'headers' |
listener | (headers: H) => void |
Returns Unsubscribe
. Unbind listener from event.
Set headers for current node.
if (navigator) {
node.setLocalHeaders({ language: navigator.language })
}
node.connection.connect()
Parameter | Type | Description |
---|
headers | object | The data object will be set as headers for current node. |
Return Promise until sync will have specific state.
If current state is correct, method will return resolved Promise.
await node.waitFor('synchronized')
console.log('Everything is synchronized')
Parameter | Type | Description |
---|
state | 'disconnected' | 'connecting' | 'sending' | 'synchronized' | The expected synchronization state value. |
Returns Promise<void>
. Promise until specific state.
Abstract interface for connection to synchronize logs over it.
For example, WebSocket or Loopback.
Is connection is enabled.
Type: boolean
.
Optional method to disconnect and unbind all even listeners.
Type: () => void
.
Start connection. Connection should be in disconnected state
from the beginning and start connection only on this method call.
This method could be called again if connection moved
to disconnected state.
Returns Promise<void>
. Promise until connection will be established.
Finish current connection.
Parameter | Type | Description |
---|
reason ? | 'error' | 'timeout' | 'destroy' | Disconnection reason. |
Subscribe for connection events. It implements nanoevents API.
Supported events:
connecting
: connection establishing was started.
connect
: connection was established by any side.
disconnect
: connection was closed by any side.
message
: message was receive from remote node.
error
: error during connection, sending or receiving.
Parameter | Type | Description |
---|
event | 'connecting' | 'connect' | 'disconnect' | Event name. |
listener | () => void | Event listener. |
Parameter | Type |
---|
event | 'error' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'message' |
listener | (msg: Message) => void |
Parameter | Type |
---|
event | 'disconnect' |
listener | (reason: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Send message to connection.
Parameter | Type | Description |
---|
message | Message | The message to be sent. |
Extends Client.
Low-level browser API for Logux.
Instead of Client
, this class prevents conflicts
between Logux instances in different tabs on single browser.
import { CrossTabClient } from '@logux/client'
const userId = document.querySelector('meta[name=user]').content
const token = document.querySelector('meta[name=token]').content
const client = new CrossTabClient({
subprotocol: '1.0.0',
server: 'wss://example.com:1337',
userId,
token
})
client.start()
Unique permanent client ID. Can be used to track this machine.
Type: string
.
Is leader tab connected to server.
Type: boolean
.
Client events log.
client.log.add(action)
Type: L
.
Node instance to synchronize logs.
if (client.node.state === 'synchronized')
Type: ClientNode<H, L>
.
Unique Logux node ID.
console.log('Client ID: ', client.nodeId)
Type: string
.
Client options.
console.log('Connecting to ' + client.options.server)
Type: ClientOptions
.
Current tab role. Only leader
tab connects to server. followers
just
listen to events from leader
.
client.on('role', () => {
console.log('Tab role:', client.role)
})
Type: 'leader' | 'candidate' | 'follower'
.
Leader tab synchronization state. It can differs
from client.node.state
(because only the leader tab keeps connection).
client.on('state', () => {
if (client.state === 'disconnected' && client.state === 'sending') {
showCloseWarning()
}
})
Type: 'disconnected' | 'connecting' | 'sending' | 'synchronized'
.
Unique tab ID. Can be used to add an action to the specific tab.
client.log.add(action, { tab: client.tabId })
Type: TabID
.
Disconnect from the server, update user, and connect again
with new credentials.
onAuth(async (userId, token) => {
showLoader()
client.changeUser(userId, token)
await client.node.waitFor('synchronized')
hideLoader()
})
You need manually chang user ID in all browser tabs.
Parameter | Type | Description |
---|
userId | string | The new user ID. |
token ? | string | Credentials for new user. |
Clear stored data. Removes action log from IndexedDB
if you used it.
signout.addEventListener('click', () => {
client.clean()
})
Returns Promise<void>
. Promise when all data will be removed.
Disconnect and stop synchronization.
shutdown.addEventListener('click', () => {
client.destroy()
})
Subscribe for synchronization events. It implements nanoevents API.
Supported events:
preadd
: action is going to be added (in current tab).
add
: action has been added to log (by any tab).
clean
: action has been removed from log (by any tab).
role
: tab role has been changed.
state
: leader tab synchronization state has been changed.
user
: user ID was changed.
client.on('add', (action, meta) => {
dispatch(action)
})
Parameter | Type | Description |
---|
event | 'role' | 'state' | The event name. |
listener | () => void | The listener function. |
Parameter | Type |
---|
event | 'user' |
listener | (userId: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Connect to server and reconnect on any connection problem.
client.start()
Wait for specific state of the leader tab.
await client.waitFor('synchronized')
hideLoader()
Parameter | Type | Description |
---|
state | 'disconnected' | 'connecting' | 'sending' | 'synchronized' | State name |
Returns Promise<void>
.
Extends LogStore.
IndexedDB
store for Logux log.
import { IndexedStore } from '@logux/client'
const client = new CrossTabClient({
…,
store: new IndexedStore()
})
import IndexedStore from '@logux/client/indexed-store'
const createStore = createLoguxCreator({
…,
store: new IndexedStore()
})
Parameter | Type | Description |
---|
name ? | string | Database name to run multiple Logux instances on same web page. |
Database name.
Type: string
.
Add action to store. Action always will have type
property.
Parameter | Type | Description |
---|
action | Action | The action to add. |
meta | Meta | Action’s metadata. |
Returns Promise<Meta | false>
. Promise with meta
for new action or false
if action with
same meta.id
was already in store.
Return action by action ID.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise <[Action, Meta] | [null, null]>
. Promise with array of action and metadata.
Change action metadata.
Parameter | Type | Description |
---|
id | ID | Action ID. |
diff | Partial<Meta> | Object with values to change in action metadata. |
Returns Promise<boolean>
. Promise with true
if metadata was changed or false
on unknown ID.
Remove all data from the store.
Returns Promise<void>
. Promise when cleaning will be finished.
Return a Promise with first page. Page object has entries
property
with part of actions and next
property with function to load next page.
If it was a last page, next
property should be empty.
This tricky API is used, because log could be very big. So we need
pagination to keep them in memory.
Parameter | Type | Description |
---|
opts ? | GetOptions | Query options. |
Returns Promise<Page>
. Promise with first page.
Return biggest added
number in store.
All actions in this log have less or same added
time.
Returns Promise<number>
. Promise with biggest added
number.
Get added
values for latest synchronized received/sent events.
Returns Promise<LastSynced>
. Promise with added
values
Remove action from store.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise<[Action, Meta] | false>
. Promise with entry if action was in store.
Remove reason from action’s metadata and remove actions without reasons.
Parameter | Type | Description |
---|
reason | string | The reason name. |
criteria | Criteria | Criteria to select action for reason removing. |
callback | ActionListener | Callback for every removed action. |
Returns Promise<void>
. Promise when cleaning will be finished.
Set added
value for latest synchronized received or/and sent events.
Parameter | Type | Description |
---|
values | LastSynced | Object with latest sent or received values. |
Returns Promise<void>
. Promise when values will be saved to store.
Extends Connection.
Is connection is enabled.
Type: boolean
.
Optional method to disconnect and unbind all even listeners.
Type: () => void
.
Start connection. Connection should be in disconnected state
from the beginning and start connection only on this method call.
This method could be called again if connection moved
to disconnected state.
Returns Promise<void>
. Promise until connection will be established.
Finish current connection.
Parameter | Type | Description |
---|
reason ? | 'error' | 'timeout' | 'destroy' | Disconnection reason. |
Subscribe for connection events. It implements nanoevents API.
Supported events:
connecting
: connection establishing was started.
connect
: connection was established by any side.
disconnect
: connection was closed by any side.
message
: message was receive from remote node.
error
: error during connection, sending or receiving.
Parameter | Type | Description |
---|
event | 'connecting' | 'connect' | 'disconnect' | Event name. |
listener | () => void | Event listener. |
Parameter | Type |
---|
event | 'error' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'message' |
listener | (msg: Message) => void |
Parameter | Type |
---|
event | 'disconnect' |
listener | (reason: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Send message to connection.
Parameter | Type | Description |
---|
message | Message | The message to be sent. |
Two paired loopback connections.
import { LocalPair, ClientNode, ServerNode } from '@logux/core'
const pair = new LocalPair()
const client = new ClientNode('client', log1, pair.left)
const server = new ServerNode('server', log2, pair.right)
Parameter | Type | Description |
---|
delay ? | number | Delay for connection and send events. Default is 1 . |
Delay for connection and send events to emulate real connection latency.
Type: number
.
First connection. Will be connected to right
one after connect()
.
new ClientNode('client, log1, pair.left)
Type: LocalConnection
.
Second connection. Will be connected to right
one after connect()
.
new ServerNode('server, log2, pair.right)
Type: LocalConnection
.
Stores actions with time marks. Log is main idea in Logux.
In most end-user tools you will work with log and should know log API.
import Log from '@logux/core'
const log = new Log({
store: new MemoryStore(),
nodeId: 'client:134'
})
log.on('add', beeper)
log.add({ type: 'beep' })
Parameter | Type | Description |
---|
opts | LogOptions<S> | Log options. |
Unique node ID. It is used in action IDs.
Type: string
.
Add action to log.
It will set id
, time
(if they was missed) and added
property
to meta
and call all listeners.
removeButton.addEventListener('click', () => {
log.add({ type: 'users:remove', user: id })
})
Returns Promise<ClientMeta | false>
. Promise with meta
if action was added to log or false
if action was already in log.
Does log already has action with this ID.
if (action.type === 'logux/undo') {
const [undidAction, undidMeta] = await log.byId(action.id)
log.changeMeta(meta.id, { reasons: undidMeta.reasons })
}
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise <[Action, ClientMeta] | [null, null]>
. Promise with array of action and metadata.
Change action metadata. You will remove action by setting reasons: []
.
await process(action)
log.changeMeta(action, { status: 'processed' })
Parameter | Type | Description |
---|
id | ID | Action ID. |
diff | Partial<ClientMeta> | Object with values to change in action metadata. |
Returns Promise<boolean>
. Promise with true
if metadata was changed or false
on unknown ID.
Iterates through all actions, from last to first.
Return false from callback if you want to stop iteration.
log.each((action, meta) => {
if (compareTime(meta.id, lastBeep) <= 0) {
return false;
} else if (action.type === 'beep') {
beep()
lastBeep = meta.id
return false;
}
})
Parameter | Type | Description |
---|
callback | ActionIterator | Function will be executed on every action. |
Returns Promise<void>
. When iteration will be finished by iterator or end of actions.
Generate next unique action ID.
const id = log.generateId()
Returns ID
. Unique ID for action.
Subscribe for log events. It implements nanoevents API. Supported events:
preadd
: when somebody try to add action to log.
It fires before ID check. The best place to add reason.
add
: when new action was added to log.
clean
: when action was cleaned from store.
const unbind = log.on('add', (action, meta) => {
if (action.type === 'beep') beep()
})
function disableBeeps () {
unbind()
}
Parameter | Type | Description |
---|
event | 'preadd' | 'add' | 'clean' | The event name. |
listener | ActionListener | The listener function. |
Returns Unsubscribe
. Unbind listener from event.
Remove reason tag from action’s metadata and remove actions without reason
from log.
onSync(lastSent) {
log.removeReason('unsynchronized', { maxAdded: lastSent })
}
Parameter | Type | Description |
---|
reason | string | The reason name. |
criteria ? | Criteria | Criteria to select action for reason removing. |
Returns Promise<void>
. Promise when cleaning will be finished.
Every Store class should provide 8 standard methods.
Parameter | Type | Description |
---|
action | Action | The action to add. |
meta | Meta | Action’s metadata. |
Add action to store. Action always will have type
property.
Parameter | Type | Description |
---|
action | Action | The action to add. |
meta | Meta | Action’s metadata. |
Returns Promise<Meta | false>
. Promise with meta
for new action or false
if action with
same meta.id
was already in store.
Return action by action ID.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise <[Action, Meta] | [null, null]>
. Promise with array of action and metadata.
Change action metadata.
Parameter | Type | Description |
---|
id | ID | Action ID. |
diff | Partial<Meta> | Object with values to change in action metadata. |
Returns Promise<boolean>
. Promise with true
if metadata was changed or false
on unknown ID.
Remove all data from the store.
Returns Promise<void>
. Promise when cleaning will be finished.
Return a Promise with first page. Page object has entries
property
with part of actions and next
property with function to load next page.
If it was a last page, next
property should be empty.
This tricky API is used, because log could be very big. So we need
pagination to keep them in memory.
Parameter | Type | Description |
---|
opts ? | GetOptions | Query options. |
Returns Promise<Page>
. Promise with first page.
Return biggest added
number in store.
All actions in this log have less or same added
time.
Returns Promise<number>
. Promise with biggest added
number.
Get added
values for latest synchronized received/sent events.
Returns Promise<LastSynced>
. Promise with added
values
Remove action from store.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise<[Action, Meta] | false>
. Promise with entry if action was in store.
Remove reason from action’s metadata and remove actions without reasons.
Parameter | Type | Description |
---|
reason | string | The reason name. |
criteria | Criteria | Criteria to select action for reason removing. |
callback | ActionListener | Callback for every removed action. |
Returns Promise<void>
. Promise when cleaning will be finished.
Set added
value for latest synchronized received or/and sent events.
Parameter | Type | Description |
---|
values | LastSynced | Object with latest sent or received values. |
Returns Promise<void>
. Promise when values will be saved to store.
Extends Error
.
Logux error in logs synchronization.
if (error.name === 'LoguxError') {
console.log('Server throws: ' + error.description)
}
Parameter | Type | Description |
---|
type | T | The error code. |
options ? | LoguxErrorOptions[T] | The error option. |
received ? | boolean | Was error received from remote node. |
Return a error description by it code.
Parameter | Type | Description |
---|
type | K | The error code. |
options ? | LoguxErrorOptions[K] | The errors options depends on error code. |
Returns string
.
Human-readable error description.
console.log('Server throws: ' + error.description)
Type: string
.
Full text of error to print in debug message.
Type: string
.
Always equal to LoguxError
. The best way to check error class.
if (error.name === 'LoguxError') {
Type: 'LoguxError'
.
Error options depends on error type.
if (error.type === 'timeout') {
console.error('A timeout was reached (' + error.options + ' ms)')
}
Type: LoguxErrorOptions[T]
.
Was error received from remote client.
Type: boolean
.
Calls which cause the error.
Type: string
.
The error code.
if (error.type === 'timeout') {
fixNetwork()
}
Type: T
.
Extends VuexStore.
Logux synchronization client.
Type: C
.
Promise until loading the state from log store.
Type: Promise<void>
.
Parameter | Type |
---|
path | string[] |
Returns boolean
.
Subscribes for store events. Supported events:
change
: when store was changed by action.
store.on('change', (state, prevState, action, meta) => {
console.log(state, prevState, action, meta)
})
Parameter | Type | Description |
---|
event | 'change' | The event name. |
listener | StateListener<S> | The listener function. |
Returns Unsubscribe
. Unbind listener from event.
Parameter | Type |
---|
path | string[] |
Parameter | Type |
---|
getter | (state: S, getters: any) => T |
cb | (value: T, oldValue: T) => void |
options ? | WatchOptions |
Returns () => void
.
Extends LogStore.
Simple memory-based log store.
It is good for tests, but not for server or client usage,
because it store all data in memory and will lose log on exit.
import { MemoryStore } from '@logux/core'
var log = new Log({
nodeId: 'server',
store: new MemoryStore()
})
Add action to store. Action always will have type
property.
Parameter | Type | Description |
---|
action | Action | The action to add. |
meta | Meta | Action’s metadata. |
Returns Promise<Meta | false>
. Promise with meta
for new action or false
if action with
same meta.id
was already in store.
Return action by action ID.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise <[Action, Meta] | [null, null]>
. Promise with array of action and metadata.
Change action metadata.
Parameter | Type | Description |
---|
id | ID | Action ID. |
diff | Partial<Meta> | Object with values to change in action metadata. |
Returns Promise<boolean>
. Promise with true
if metadata was changed or false
on unknown ID.
Remove all data from the store.
Returns Promise<void>
. Promise when cleaning will be finished.
Return a Promise with first page. Page object has entries
property
with part of actions and next
property with function to load next page.
If it was a last page, next
property should be empty.
This tricky API is used, because log could be very big. So we need
pagination to keep them in memory.
Parameter | Type | Description |
---|
opts ? | GetOptions | Query options. |
Returns Promise<Page>
. Promise with first page.
Return biggest added
number in store.
All actions in this log have less or same added
time.
Returns Promise<number>
. Promise with biggest added
number.
Get added
values for latest synchronized received/sent events.
Returns Promise<LastSynced>
. Promise with added
values
Remove action from store.
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise<[Action, Meta] | false>
. Promise with entry if action was in store.
Remove reason from action’s metadata and remove actions without reasons.
Parameter | Type | Description |
---|
reason | string | The reason name. |
criteria | Criteria | Criteria to select action for reason removing. |
callback | ActionListener | Callback for every removed action. |
Returns Promise<void>
. Promise when cleaning will be finished.
Set added
value for latest synchronized received or/and sent events.
Parameter | Type | Description |
---|
values | LastSynced | Object with latest sent or received values. |
Returns Promise<void>
. Promise when values will be saved to store.
Extends Connection.
Wrapper for Connection for reconnecting it on every disconnect.
import { ClientNode, Reconnect } from '@logux/core'
const recon = new Reconnect(connection)
new ClientNode(nodeId, log, recon, options)
Fails attempts since the last connected state.
Type: number
.
Is connection is enabled.
Type: boolean
.
Are we in the middle of connecting.
Type: boolean
.
Unbind all listeners and disconnect. Use it if you will not need
this class anymore.
Type: () => void
.
Should we reconnect connection on next connection break.
Next connect
call will set to true
.
function lastTry () {
recon.reconnecting = false
}
Type: boolean
.
Start connection. Connection should be in disconnected state
from the beginning and start connection only on this method call.
This method could be called again if connection moved
to disconnected state.
Returns Promise<void>
. Promise until connection will be established.
Finish current connection.
Parameter | Type | Description |
---|
reason ? | 'error' | 'timeout' | 'destroy' | Disconnection reason. |
Subscribe for connection events. It implements nanoevents API.
Supported events:
connecting
: connection establishing was started.
connect
: connection was established by any side.
disconnect
: connection was closed by any side.
message
: message was receive from remote node.
error
: error during connection, sending or receiving.
Parameter | Type | Description |
---|
event | 'connecting' | 'connect' | 'disconnect' | Event name. |
listener | () => void | Event listener. |
Parameter | Type |
---|
event | 'error' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'message' |
listener | (msg: Message) => void |
Parameter | Type |
---|
event | 'disconnect' |
listener | (reason: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Send message to connection.
Parameter | Type | Description |
---|
message | Message | The message to be sent. |
Extends Log.
Log to be used in tests. It already has memory store, node ID,
and special test timer.
Use TestTime
to create test log.
import { TestTime } from '@logux/core'
it('tests log', () => {
const log = TestTime.getLog()
})
it('tests 2 logs', () => {
const time = new TestTime()
const log1 = time.nextLog()
const log2 = time.nextLog()
})
Unique node ID. It is used in action IDs.
Type: string
.
Return all action (without metadata) inside log, sorted by created time.
This shortcut works only with MemoryStore
.
expect(log.action).toEqual([
{ type: 'A' }
])
Returns Action[]
.
Add action to log.
It will set id
, time
(if they was missed) and added
property
to meta
and call all listeners.
removeButton.addEventListener('click', () => {
log.add({ type: 'users:remove', user: id })
})
Returns Promise<ClientMeta | false>
. Promise with meta
if action was added to log or false
if action was already in log.
Does log already has action with this ID.
if (action.type === 'logux/undo') {
const [undidAction, undidMeta] = await log.byId(action.id)
log.changeMeta(meta.id, { reasons: undidMeta.reasons })
}
Parameter | Type | Description |
---|
id | ID | Action ID. |
Returns Promise <[Action, ClientMeta] | [null, null]>
. Promise with array of action and metadata.
Change action metadata. You will remove action by setting reasons: []
.
await process(action)
log.changeMeta(action, { status: 'processed' })
Parameter | Type | Description |
---|
id | ID | Action ID. |
diff | Partial<ClientMeta> | Object with values to change in action metadata. |
Returns Promise<boolean>
. Promise with true
if metadata was changed or false
on unknown ID.
Iterates through all actions, from last to first.
Return false from callback if you want to stop iteration.
log.each((action, meta) => {
if (compareTime(meta.id, lastBeep) <= 0) {
return false;
} else if (action.type === 'beep') {
beep()
lastBeep = meta.id
return false;
}
})
Parameter | Type | Description |
---|
callback | ActionIterator | Function will be executed on every action. |
Returns Promise<void>
. When iteration will be finished by iterator or end of actions.
Return all entries (with metadata) inside log, sorted by created time.
This shortcut works only with MemoryStore
.
expect(log.action).toEqual([
[{ type: 'A' }, { id: '1 test1 0', time: 1, added: 1, reasons: ['t'] }]
])
Returns [Action, Meta][]
.
Generate next unique action ID.
const id = log.generateId()
Returns ID
. Unique ID for action.
Subscribe for log events. It implements nanoevents API. Supported events:
preadd
: when somebody try to add action to log.
It fires before ID check. The best place to add reason.
add
: when new action was added to log.
clean
: when action was cleaned from store.
const unbind = log.on('add', (action, meta) => {
if (action.type === 'beep') beep()
})
function disableBeeps () {
unbind()
}
Parameter | Type | Description |
---|
event | 'preadd' | 'add' | 'clean' | The event name. |
listener | ActionListener | The listener function. |
Returns Unsubscribe
. Unbind listener from event.
Remove reason tag from action’s metadata and remove actions without reason
from log.
onSync(lastSent) {
log.removeReason('unsynchronized', { maxAdded: lastSent })
}
Parameter | Type | Description |
---|
reason | string | The reason name. |
criteria ? | Criteria | Criteria to select action for reason removing. |
Returns Promise<void>
. Promise when cleaning will be finished.
Extends LocalPair.
Two paired loopback connections with events tracking
to be used in Logux tests.
import { TestPair } from '@logux/core'
it('tracks events', async () => {
const pair = new TestPair()
const client = new ClientNode(pair.right)
await pair.left.connect()
expect(pair.leftEvents).toEqual('connect')
await pair.left.send(msg)
expect(pair.leftSent).toEqual([msg])
})
Parameter | Type | Description |
---|
delay ? | number | Delay for connection and send events. Default is 1 . |
Delay for connection and send events to emulate real connection latency.
Type: number
.
First connection. Will be connected to right
one after connect()
.
new ClientNode('client, log1, pair.left)
Type: LocalConnection
.
Emitted events from left
connection.
await pair.left.connect()
pair.leftEvents
Type: string[][]
.
Node instance used in this test, connected with left
.
function createTest () {
test = new TestPair()
test.leftNode = ClientNode('client', log, test.left)
return test
}
Type: BaseNode<{ }, TestLog>
.
Sent messages from left
connection.
await pair.left.send(msg)
pair.leftSent
Type: Message[]
.
Second connection. Will be connected to right
one after connect()
.
new ServerNode('server, log2, pair.right)
Type: LocalConnection
.
Emitted events from right
connection.
await pair.right.connect()
pair.rightEvents
Type: string[][]
.
Node instance used in this test, connected with right
.
function createTest () {
test = new TestPair()
test.rightNode = ServerNode('client', log, test.right)
return test
}
Type: BaseNode<{ }, TestLog>
.
Sent messages from right
connection.
await pair.right.send(msg)
pair.rightSent
Type: Message[]
.
Clear all connections events and messages to test only last events.
await client.connection.connect()
pair.clear()
await client.log.add({ type: 'a' })
expect(pair.leftSent).toEqual([
['sync', …]
])
Return Promise until next event.
pair.left.send(['test'])
await pair.wait('left')
pair.leftSend
Parameter | Type | Description |
---|
receiver ? | 'left' | 'right' | Wait for specific receiver event. |
Returns Promise<void>
. Promise until next event.
Creates special logs for test purposes.
Real logs use real time in actions ID,
so log content will be different on every test execution.
To fix it Logux has special logs for tests with simple sequence timer.
All logs from one test should share same time. This is why you should
use log creator to share time between all logs in one test.
import { TestTime } from '@logux/core'
it('tests log', () => {
const log = TestTime.getLog()
})
it('tests 2 logs', () => {
const time = new TestTime()
const log1 = time.nextLog()
const log2 = time.nextLog()
})
Shortcut to create time and generate single log.
Use it only if you need one log in test.
it('tests log', () => {
const log = TestTime.getLog()
})
Returns TestLog
.
Last letd number in log’s nodeId
.
Type: number
.
Return next test log in same time.
it('tests 2 logs', () => {
const time = new TestTime()
const log1 = time.nextLog()
const log2 = time.nextLog()
})
Returns TestLog
.
Extends Connection.
Logux connection for browser WebSocket.
import { WsConnection } from '@logux/core'
const connection = new WsConnection('wss://logux.example.com/')
const node = new ClientNode(nodeId, log, connection, opts)
Parameter | Type | Description |
---|
url | string | WebSocket server URL. |
Class ? | any | |
opts ? | any | Extra option for WebSocket constructor. |
Is connection is enabled.
Type: boolean
.
Optional method to disconnect and unbind all even listeners.
Type: () => void
.
WebSocket instance.
Type: WS
.
Start connection. Connection should be in disconnected state
from the beginning and start connection only on this method call.
This method could be called again if connection moved
to disconnected state.
Returns Promise<void>
. Promise until connection will be established.
Finish current connection.
Parameter | Type | Description |
---|
reason ? | 'error' | 'timeout' | 'destroy' | Disconnection reason. |
Subscribe for connection events. It implements nanoevents API.
Supported events:
connecting
: connection establishing was started.
connect
: connection was established by any side.
disconnect
: connection was closed by any side.
message
: message was receive from remote node.
error
: error during connection, sending or receiving.
Parameter | Type | Description |
---|
event | 'connecting' | 'connect' | 'disconnect' | Event name. |
listener | () => void | Event listener. |
Parameter | Type |
---|
event | 'error' |
listener | (error: Error) => void |
Parameter | Type |
---|
event | 'message' |
listener | (msg: Message) => void |
Parameter | Type |
---|
event | 'disconnect' |
listener | (reason: string) => void |
Returns Unsubscribe
. Unbind listener from event.
Send message to connection.
Parameter | Type | Description |
---|
message | Message | The message to be sent. |
Functions
Highlight tabs on synchronization errors.
import { attention } from '@logux/client'
attention(client)
Parameter | Type | Description |
---|
client | Client | Observed Client instance. |
Returns () => void
. Unbind listener.
Display Logux widget in browser.
import { badge, badgeEn } from '@logux/client'
import { badgeStyles } from '@logux/client/badge/styles'
badge(client, {
messages: badgeEn,
styles: {
...badgeStyles,
synchronized: { backgroundColor: 'green' }
},
position: 'top-left'
})
Parameter | Type | Description |
---|
client | Client | Observed Client instance. |
opts | BadgeOptions | Widget settings. |
Returns () => void
. Unbind badge listener and remove widget from DOM.
Show confirm popup, when user close tab with non-synchronized actions.
import { confirm } from '@logux/client'
confirm(client)
Parameter | Type | Description |
---|
client | Client | Observed Client instance. |
Returns () => void
. Unbind listener.
Connects Logux client to Vuex’s createStore
function.
import { CrossTabClient, createStoreCreator } from '@logux/vuex'
const client = new CrossTabClient({
subprotocol: '1.0.0',
server: process.env.NODE_ENV === 'development'
? 'ws://localhost:31337'
: 'wss://logux.example.com',
userId: 'anonymous',
token: ''
})
const createStore = createStoreCreator(client)
const store = createStore({
state: {},
mutations: {},
actions: {},
modules: {}
})
store.client.start()
Parameter | Type | Description |
---|
client | C | Logux Client. |
options ? | LoguxVuexOptions | Logux Vuex options. |
Returns createStore<L, C>
. Vuex’s createStore
function, compatible with Logux Client.
Pass all common tests for Logux store to callback.
import { eachStoreCheck } from '@logux/core'
eachStoreCheck((desc, creator) => {
it(desc, creator(() => new CustomStore()))
})
Parameter | Type | Description |
---|
test | (name: string, testCreator: (storeCreator: () => LogStore) => () => void) => void | Callback to create tests in your test framework. |
Change favicon to show Logux synchronization status.
import { favicon } from '@logux/client'
favicon(client, {
normal: '/favicon.ico',
offline: '/offline.ico',
error: '/error.ico'
})
Parameter | Type | Description |
---|
client | Client | Observed Client instance. |
links | FaviconLinks | Favicon links. |
Returns () => void
. Unbind listener.
Compare time, when log entries were created.
It uses meta.time
and meta.id
to detect entries order.
import { isFirstOlder } from '@logux/core'
if (isFirstOlder(lastBeep, meta) {
beep(action)
lastBeep = meta
}
Parameter | Type | Description |
---|
firstMeta | Meta | undefined | Some action’s metadata. |
secondMeta | Meta | undefined | Other action’s metadata. |
Returns boolean
.
Display Logux events in browser console.
import { log } from '@logux/client'
log(client, { ignoreActions: ['user/add'] })
Parameter | Type | Description |
---|
client | Client | Observed Client instance. |
messages ? | LogMessages | Disable specific message types. |
Returns () => void
. Unbind listener.
Parse meta.id
or Node ID into component: user ID, client ID, node ID.
import { parseId } from '@logux/core'
const { userId, clientId } = parseId(meta.id)
Parameter | Type | Description |
---|
id | string | Action or Node ID |
Returns IDComponents
.
Low-level function to show Logux synchronization status with your custom UI.
It is used in badge
widget.
import { status } from '@logux/client'
status(client, current => {
updateUI(current)
})
Returns () => void
. Unbind listener.
Composable function that injects store into the component.
import { useStore } from '@logux/vuex'
export default {
setup () {
let store = useStore()
store.commit.sync('user/rename')
}
}
Returns LoguxVuexStore<S, L, C>
. Store instance.
Composable function that subscribes
for channels during component initialization
and unsubscribes on unmount.
It watches for channels
changes
and returns isSubscribing
flag that indicates loading state.
<template>
<div v-if="isSubscribing">Loading</div>
<h1 v-else>{{ user.name }}</h1>
</template>
<script>
import { toRefs } from 'vue'
import { useStore, useSubscription } from '@logux/vuex'
export default {
props: ['userId'],
setup (props) {
let store = useStore()
let { userId } = toRefs(props)
let isSubscribing = useSubscription(() => [`user/${userId.value}`])
let user = computed(() => store.state.users[userId.value])
return { isSubscribing, user }
}
})
</script>
Returns Ref<boolean>
. true
during data loading.
Variables
Component-wrapper that subscribes
for channels during component initialization
and unsubscribes on unmount.
It watches for channels
changes
and isSubscribing
indicates loading state.
<template>
<subscribe :channels="channels" v-slot="{ isSubscribing }">
<h1 v-if="isSubscribing">Loading</h1>
<h1 v-else>{{ user.name }}</h1>
</subscribe>
</template>
<script>
import { toRefs, computed } from 'vue'
import { useStore, Subscribe } from '@logux/vuex'
export default {
components: { Subscribe },
props: ['userId'],
setup (props) {
let store = useStore()
let { userId } = toRefs(props)
let user = computed(() => store.state.users[userId.value])
let channels = computed(() => [`users/${userId.value}`])
return {
user,
channels
}
}
}
</script>
Type: { }
.
Types
Property | Type | Description |
---|
type | string | Action type name. |
Type: Action & { [extra: string]: any }
.
Parameter | Type |
---|
nodeId | string |
token | string |
headers | H | { } |
Returns Promise<boolean>
.
Type: { denied: string, disconnected: string, error: string, protocolError: string, sending: string, syncError: string, synchronized: string, wait: string }
.
Property | Type | Description |
---|
duration ? | number | Synchronized state duration. Default is 3000 . |
messages | BadgeMessages | Widget text for different states. |
position ? | 'top-left' | 'top-center' | 'top-right' | 'middle-left' | 'middle-center' | 'middle-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | Widget position. Default is bottom-right . |
styles | BadgeStyles | Inline styles for different states. |
Type: { base: object, connecting: object, disconnected: object, error: object, icon: { disconnected: string, error: string, protocolError: string, sending: string, synchronized: string, wait: string }, protocolError: object, sending: object, synchronized: object, text: object, wait: object }
.
Type: string | { channel: string }
.
Extends Meta.
Property | Type | Description |
---|
added | number | Sequence number of action in current log. Log fills it. |
id | ID | Action unique ID. Log sets it automatically. |
keepLast ? | string | Set value to reasons and this reason from old action. |
reasons | string[] | Why action should be kept in log. Action without reasons will be removed. |
subprotocol ? | string | Set code as reason and remove this reasons from previous actions. |
time | number | Action created time in current node time. Milliseconds since UNIX epoch. |
noAutoReason ? | boolean | Disable setting timeTravel reason. |
sync ? | boolean | This action should be synchronized with other browser tabs and server. |
tab ? | TabID | Action should be visible only for browser tab with the same client.tabId . |
Property | Type | Description |
---|
allowDangerousProtocol ? | boolean | Do not show warning when using ws:// in production. |
attempts ? | number | Maximum reconnection attempts. Default is Infinity . |
maxDelay ? | number | Maximum delay between reconnections. Default is 5000 . |
minDelay ? | number | Minimum delay between reconnections. Default is 1000 . |
ping ? | number | Milliseconds since last message to test connection by sending ping.
Default is 10000 . |
prefix ? | string | Prefix for IndexedDB database to run multiple Logux instances
in the same browser. Default is logux . |
server | string | Connection | Server URL. |
store ? | LogStore | Store to save log data. Default is MemoryStore . |
subprotocol | string | Client subprotocol version in SemVer format. |
time ? | TestTime | Test time to test client. |
timeout ? | number | Timeout in milliseconds to break connection. Default is 20000 . |
token ? | string | TokenGenerator | Client credentials for authentication. |
userId | string | User ID. |
Property | Type | Description |
---|
id ? | ID | Remove reason only for action with id . |
maxAdded ? | number | Remove reason only for actions with lower added . |
minAdded ? | number | Remove reason only for actions with bigger added . |
olderThan ? | Meta | Remove reason only older than specific action. |
youngerThan ? | Meta | Remove reason only younger than specific action. |
Type: { [key: string]: undefined }
.
Property | Type | Description |
---|
error ? | string | Error favicon link. |
normal ? | string | Default favicon link. By default, it will be taken from current favicon. |
offline ? | string | Offline favicon link. |
Property | Type | Description |
---|
order ? | 'created' | 'added' | Sort entries by created time or when they was added to current log. |
Action unique ID accross all nodes.
"1564508138460 380:R7BNGAP5:px3-J3oc 0"
Type: string
.
Type: { clientId: string, nodeId: string, userId: string | undefined }
.
Property | Type | Description |
---|
received | number | The added value of latest received event. |
sent | number | The added value of latest sent event. |
Property | Type | Description |
---|
add ? | boolean | Disable action added messages. |
clean ? | boolean | Disable action cleaned messages. |
error ? | boolean | Disable error messages. |
ignoreActions ? | string[] | Disable action messages with specific types. |
role ? | boolean | Disable tab role messages. |
state ? | boolean | Disable connection state messages. |
user ? | boolean | Disable user ID changing. |
Property | Type | Description |
---|
nodeId | string | Unique current machine name. |
store | S | Store for log. |
Type: { bruteforce: void, timeout: number, unknown-message: string, wrong-credentials: void, wrong-format: string, wrong-protocol: Versions, wrong-subprotocol: Versions }
.
Adds cross-tab action to log and updates store state.
This action will be visible only for all tabs.
store.commit.crossTab(
{ type: 'CHANGE_FAVICON', favicon },
{ reasons: ['lastFavicon'] }
).then(meta => {
store.log.removeReason('lastFavicon', { maxAdded: meta.added - 1 })
})
Parameter | Type | Description |
---|
type | string | Action type. |
payload ? | any | Action’s payload. |
meta ? | Partial<ClientMeta> | Action’s metadata. |
Returns Promise<ClientMeta>
. Promise when action will be processed by the server.
Adds local action to log and updates store state.
This action will be visible only for current tab.
store.commit.local(
{ type: 'OPEN_MENU' },
{ reasons: ['lastMenu'] }
).then(meta => {
store.log.removeReason('lastMenu', { maxAdded: meta.added - 1 })
})
Parameter | Type | Description |
---|
type | string | Action type. |
payload ? | any | Action’s payload. |
meta ? | Partial<ClientMeta> | Action’s metadata. |
Returns Promise<ClientMeta>
. Promise when action will be processed by the server.
Adds sync action to log and updates store state.
This action will be visible only for server and all browser tabs.
store.commit.sync(
{ type: 'CHANGE_NAME', name },
{ reasons: ['lastName'] }
).then(meta => {
store.log.removeReason('lastName', { maxAdded: meta.added - 1 })
})
Parameter | Type | Description |
---|
type | string | Action type. |
payload ? | any | Action’s payload. |
meta ? | Partial<ClientMeta> | Action’s metadata. |
Returns Promise<ClientMeta>
. Promise when action will be processed by the server.
Property | Type | Description |
---|
cleanEvery ? | number | How often we need to clean log from old actions. Default is every 25
actions. |
onMissedHistory ? | (action: Action) => void | Callback when there is no history to replay actions accurate. |
reasonlessHistory ? | number | How many actions without meta.reasons will be kept for time travel.
Default is 1000 . |
saveStateEvery ? | number | How often save state to history. Default is 50 . |
Type: ['error', keyof LoguxErrorOptions, any] | ['connect', number, string, number, object] | ['connected', number, string, [number, number], object] | ['ping', number] | ['pong', number] | ['sync', number, object, object] | ['synced', number] | ['debug', 'error', string] | ['headers', object]
.
Property | Type | Description |
---|
added | number | Sequence number of action in current log. Log fills it. |
id | ID | Action unique ID. Log sets it automatically. |
keepLast ? | string | Set value to reasons and this reason from old action. |
reasons | string[] | Why action should be kept in log. Action without reasons will be removed. |
subprotocol ? | string | Set code as reason and remove this reasons from previous actions. |
time | number | Action created time in current node time. Milliseconds since UNIX epoch. |
Property | Type | Description |
---|
auth ? | Authentificator<H> | Function to check client credentials. |
fixTime ? | boolean | Detect difference between client and server and fix time
in synchronized actions. |
inFilter ? | Filter | Function to filter actions from remote node. Best place for access control. |
inMap ? | Mapper | Map function to change remote node’s action before put it to current log. |
outFilter ? | Filter | Filter function to select actions to synchronization. |
outMap ? | Mapper | Map function to change action before sending it to remote client. |
ping ? | number | Milliseconds since last message to test connection by sending ping. |
subprotocol ? | string | Application subprotocol version in SemVer format. |
timeout ? | number | Timeout in milliseconds to wait answer before disconnect. |
token ? | string | TokenGenerator | Client credentials. For example, access token. |
Property | Type | Description |
---|
attempts ? | number | Maximum reconnecting attempts. |
maxDelay ? | number | Maximum delay between reconnecting. |
minDelay ? | number | Minimum delay between reconnecting. |
Parameter | Type |
---|
state | S |
prevState | S |
action | A |
meta | ClientMeta |
Parameter | Type |
---|
current | 'synchronized' | 'synchronizedAfterWait' | 'disconnected' | 'connecting' | 'connectingAfterWait' | 'protocolError' | 'syncError' | 'error' | 'denied' | 'wait' |
details | undefined | Error | { action: Action, meta: ClientMeta } |
Property | Type | Description |
---|
duration ? | number | Synchronized state duration. Default is 3000 . |
Property | Type | Description |
---|
nodeId | string | Unique log name. |
store | LogStore | Store for log. Will use MemoryStore by default. |
Type: { supported: string, used: string }
.
Vuex’s createStore
function, compatible with Logux Client.
Returns LoguxVuexStore<S, L, C>
. Vuex store, compatible with Logux Client.
Property | Type | Description |
---|
debounce ? | number | Delay in milliseconds to avoid returning true when switching between channels . |
store ? | LoguxVuexStore | Logux Vuex store. |