This repository has been archived by the owner on Jun 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 231
/
sync_machine.coffee
88 lines (70 loc) · 2.21 KB
/
sync_machine.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
'use strict'
# Simple finite state machine for synchronization of models/collections
# Three states: unsynced, syncing and synced
# Several transitions between them
# Fires Backbone events on every transition
# (unsynced, syncing, synced; syncStateChange)
# Provides shortcut methods to call handlers when a given state is reached
# (named after the events above)
UNSYNCED = 'unsynced'
SYNCING = 'syncing'
SYNCED = 'synced'
STATE_CHANGE = 'syncStateChange'
SyncMachine =
_syncState: UNSYNCED
_previousSyncState: null
# Get the current state
# ---------------------
syncState: ->
@_syncState
isUnsynced: ->
@_syncState is UNSYNCED
isSynced: ->
@_syncState is SYNCED
isSyncing: ->
@_syncState is SYNCING
# Transitions
# -----------
unsync: ->
if @_syncState in [SYNCING, SYNCED]
@_previousSync = @_syncState
@_syncState = UNSYNCED
@trigger @_syncState, this, @_syncState
@trigger STATE_CHANGE, this, @_syncState
# when UNSYNCED do nothing
return
beginSync: ->
if @_syncState in [UNSYNCED, SYNCED]
@_previousSync = @_syncState
@_syncState = SYNCING
@trigger @_syncState, this, @_syncState
@trigger STATE_CHANGE, this, @_syncState
# when SYNCING do nothing
return
finishSync: ->
if @_syncState is SYNCING
@_previousSync = @_syncState
@_syncState = SYNCED
@trigger @_syncState, this, @_syncState
@trigger STATE_CHANGE, this, @_syncState
# when SYNCED, UNSYNCED do nothing
return
abortSync: ->
if @_syncState is SYNCING
@_syncState = @_previousSync
@_previousSync = @_syncState
@trigger @_syncState, this, @_syncState
@trigger STATE_CHANGE, this, @_syncState
# when UNSYNCED, SYNCED do nothing
return
# Create shortcut methods to bind a handler to a state change
# -----------------------------------------------------------
for event in [UNSYNCED, SYNCING, SYNCED, STATE_CHANGE]
do (event) ->
SyncMachine[event] = (callback, context = this) ->
@on event, callback, context
callback.call(context) if @_syncState is event
# You’re frozen when your heart’s not open.
Object.freeze SyncMachine
# Return our creation.
module.exports = SyncMachine