render_sync 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +153 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +521 -0
- data/Rakefile +9 -0
- data/app/assets/javascripts/sync.coffee +355 -0
- data/app/controllers/sync/refetches_controller.rb +56 -0
- data/app/helpers/render_sync/config_helper.rb +15 -0
- data/config/routes.rb +3 -0
- data/config/sync.yml +21 -0
- data/lib/generators/render_sync/install_generator.rb +14 -0
- data/lib/generators/render_sync/templates/sync.ru +14 -0
- data/lib/generators/render_sync/templates/sync.yml +34 -0
- data/lib/render_sync.rb +174 -0
- data/lib/render_sync/action.rb +39 -0
- data/lib/render_sync/actions.rb +114 -0
- data/lib/render_sync/channel.rb +23 -0
- data/lib/render_sync/clients/dummy.rb +22 -0
- data/lib/render_sync/clients/faye.rb +104 -0
- data/lib/render_sync/clients/pusher.rb +77 -0
- data/lib/render_sync/controller_helpers.rb +33 -0
- data/lib/render_sync/engine.rb +24 -0
- data/lib/render_sync/erb_tracker.rb +49 -0
- data/lib/render_sync/faye_extension.rb +45 -0
- data/lib/render_sync/model.rb +174 -0
- data/lib/render_sync/model_actions.rb +60 -0
- data/lib/render_sync/model_change_tracking.rb +97 -0
- data/lib/render_sync/model_syncing.rb +65 -0
- data/lib/render_sync/model_touching.rb +35 -0
- data/lib/render_sync/partial.rb +112 -0
- data/lib/render_sync/partial_creator.rb +47 -0
- data/lib/render_sync/reactor.rb +48 -0
- data/lib/render_sync/refetch_model.rb +21 -0
- data/lib/render_sync/refetch_partial.rb +43 -0
- data/lib/render_sync/refetch_partial_creator.rb +21 -0
- data/lib/render_sync/renderer.rb +19 -0
- data/lib/render_sync/resource.rb +115 -0
- data/lib/render_sync/scope.rb +113 -0
- data/lib/render_sync/scope_definition.rb +30 -0
- data/lib/render_sync/view_helpers.rb +106 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/sync/users/_show.html.erb +1 -0
- data/test/dummy/app/views/sync/users/refetch/_show.html.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +22 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +8 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/log/test.log +626 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/em_minitest_spec.rb +100 -0
- data/test/fixtures/sync_auth_token_missing.yml +6 -0
- data/test/fixtures/sync_erb.yml +7 -0
- data/test/fixtures/sync_faye.yml +7 -0
- data/test/fixtures/sync_pusher.yml +8 -0
- data/test/models/group.rb +3 -0
- data/test/models/project.rb +2 -0
- data/test/models/todo.rb +8 -0
- data/test/models/user.rb +82 -0
- data/test/sync/abstract_controller.rb +3 -0
- data/test/sync/action_test.rb +82 -0
- data/test/sync/channel_test.rb +15 -0
- data/test/sync/config_test.rb +25 -0
- data/test/sync/erb_tracker_test.rb +72 -0
- data/test/sync/faye_extension_test.rb +87 -0
- data/test/sync/message_test.rb +159 -0
- data/test/sync/model_test.rb +315 -0
- data/test/sync/partial_creator_test.rb +35 -0
- data/test/sync/partial_test.rb +107 -0
- data/test/sync/protected_attributes_test.rb +39 -0
- data/test/sync/reactor_test.rb +18 -0
- data/test/sync/refetch_model_test.rb +26 -0
- data/test/sync/refetch_partial_creator_test.rb +16 -0
- data/test/sync/refetch_partial_test.rb +74 -0
- data/test/sync/renderer_test.rb +19 -0
- data/test/sync/resource_test.rb +181 -0
- data/test/sync/scope_definition_test.rb +39 -0
- data/test/sync/scope_test.rb +113 -0
- data/test/test_helper.rb +66 -0
- data/test/travis/sync.ru +14 -0
- data/test/travis/sync.yml +21 -0
- metadata +317 -0
data/Rakefile
ADDED
@@ -0,0 +1,355 @@
|
|
1
|
+
$ = jQuery
|
2
|
+
|
3
|
+
@RenderSync =
|
4
|
+
|
5
|
+
ready: false
|
6
|
+
readyQueue: []
|
7
|
+
|
8
|
+
init: ->
|
9
|
+
$ =>
|
10
|
+
return unless RenderSyncConfig? && RenderSync[RenderSyncConfig.adapter]
|
11
|
+
@adapter ||= new RenderSync[RenderSyncConfig.adapter]
|
12
|
+
return if @isReady() || !@adapter.available()
|
13
|
+
@ready = true
|
14
|
+
@connect()
|
15
|
+
@flushReadyQueue()
|
16
|
+
@bindUnsubscribe()
|
17
|
+
|
18
|
+
|
19
|
+
# Handle Turbolinks teardown, unsubscribe from all channels before transition
|
20
|
+
bindUnsubscribe: ->
|
21
|
+
$(document).bind "page:before-change", => @adapter.unsubscribeAll()
|
22
|
+
$(document).bind "page:restore", => @reexecuteScripts()
|
23
|
+
|
24
|
+
|
25
|
+
# Handle Turbolinks cache restore, re-eval all sync script tags
|
26
|
+
reexecuteScripts: ->
|
27
|
+
for script in $("script[data-sync-id]")
|
28
|
+
eval($(script).html())
|
29
|
+
|
30
|
+
|
31
|
+
onConnectFailure: (error) -> #noop
|
32
|
+
|
33
|
+
connect: -> @adapter.connect()
|
34
|
+
|
35
|
+
isConnected: -> @adapter.isConnected()
|
36
|
+
|
37
|
+
onReady: (callback) ->
|
38
|
+
if @isReady()
|
39
|
+
callback()
|
40
|
+
else
|
41
|
+
@readyQueue.push callback
|
42
|
+
|
43
|
+
|
44
|
+
flushReadyQueue: ->
|
45
|
+
@onReady(callback) for callback in @readyQueue
|
46
|
+
@readyQueue = []
|
47
|
+
|
48
|
+
|
49
|
+
isReady: -> @ready
|
50
|
+
|
51
|
+
camelize: (str) ->
|
52
|
+
str.replace /(?:^|[-_])(\w)/g, (match, camel) -> camel?.toUpperCase() ? ''
|
53
|
+
|
54
|
+
|
55
|
+
# Find View class to render based on partial and resource names
|
56
|
+
# The class name is looked up based on
|
57
|
+
# 1. The camelized version of the concatenated snake case resource
|
58
|
+
# and partial names.
|
59
|
+
# 2. The camelized version of the snake cased partialName.
|
60
|
+
#
|
61
|
+
# Examples
|
62
|
+
# partialName 'list_row', resourceName 'todo', order of lookup:
|
63
|
+
# RenderSync.TodoListRow
|
64
|
+
# RenderSync.ListRow
|
65
|
+
# RenderSync.View
|
66
|
+
#
|
67
|
+
# Defaults to RenderSync.View if no custom view class has been defined
|
68
|
+
viewClassFromPartialName: (partialName, resourceName) ->
|
69
|
+
RenderSync[@camelize("#{resourceName}_#{partialName}")] ?
|
70
|
+
RenderSync[@camelize(partialName)] ?
|
71
|
+
RenderSync.View
|
72
|
+
|
73
|
+
|
74
|
+
class RenderSync.Adapter
|
75
|
+
|
76
|
+
subscriptions: []
|
77
|
+
|
78
|
+
unsubscribeAll: ->
|
79
|
+
subscription.cancel() for subscription in @subscriptions
|
80
|
+
@subscriptions = []
|
81
|
+
|
82
|
+
# If the channel is already subscribed, we do two things:
|
83
|
+
# 1. cancel() the subscription
|
84
|
+
# 2. remove the channel from our @subscriptions array
|
85
|
+
unsubscribeChannel: (channel) ->
|
86
|
+
for sub, index in @subscriptions when sub.channel is channel
|
87
|
+
sub.cancel()
|
88
|
+
@subscriptions.splice(index, 1)
|
89
|
+
return
|
90
|
+
|
91
|
+
subscribe: (channel, callback) ->
|
92
|
+
@unsubscribeChannel(channel)
|
93
|
+
subscription = new RenderSync[RenderSyncConfig.adapter].Subscription(@client, channel, callback)
|
94
|
+
@subscriptions.push(subscription)
|
95
|
+
subscription
|
96
|
+
|
97
|
+
|
98
|
+
class RenderSync.Faye extends RenderSync.Adapter
|
99
|
+
|
100
|
+
subscriptions: []
|
101
|
+
|
102
|
+
available: ->
|
103
|
+
!!window.Faye
|
104
|
+
|
105
|
+
connect: ->
|
106
|
+
@client = new window.Faye.Client(RenderSyncConfig.server)
|
107
|
+
|
108
|
+
isConnected: -> @client?.getState() is "CONNECTED"
|
109
|
+
|
110
|
+
|
111
|
+
class RenderSync.Faye.Subscription
|
112
|
+
|
113
|
+
constructor: (@client, channel, callback) ->
|
114
|
+
@channel = channel
|
115
|
+
@fayeSub = @client.subscribe channel, callback
|
116
|
+
|
117
|
+
cancel: ->
|
118
|
+
@fayeSub.cancel()
|
119
|
+
|
120
|
+
|
121
|
+
class RenderSync.Pusher extends RenderSync.Adapter
|
122
|
+
|
123
|
+
subscriptions: []
|
124
|
+
|
125
|
+
available: ->
|
126
|
+
!!window.Pusher
|
127
|
+
|
128
|
+
connect: ->
|
129
|
+
opts =
|
130
|
+
encrypted: RenderSyncConfig.pusher_encrypted
|
131
|
+
|
132
|
+
opts.wsHost = RenderSyncConfig.pusher_ws_host if RenderSyncConfig.pusher_ws_host
|
133
|
+
opts.wsPort = RenderSyncConfig.pusher_ws_port if RenderSyncConfig.pusher_ws_port
|
134
|
+
opts.wssPort = RenderSyncConfig.pusher_wss_port if RenderSyncConfig.pusher_wss_port
|
135
|
+
|
136
|
+
@client = new window.Pusher(RenderSyncConfig.api_key, opts)
|
137
|
+
|
138
|
+
isConnected: -> @client?.connection.state is "connected"
|
139
|
+
|
140
|
+
subscribe: (channel, callback) ->
|
141
|
+
@unsubscribeChannel(channel)
|
142
|
+
subscription = new RenderSync.Pusher.Subscription(@client, channel, callback)
|
143
|
+
@subscriptions.push(subscription)
|
144
|
+
subscription
|
145
|
+
|
146
|
+
|
147
|
+
class RenderSync.Pusher.Subscription
|
148
|
+
constructor: (@client, channel, callback) ->
|
149
|
+
@channel = channel
|
150
|
+
|
151
|
+
pusherSub = @client.subscribe(channel)
|
152
|
+
pusherSub.bind 'sync', callback
|
153
|
+
|
154
|
+
cancel: ->
|
155
|
+
@client.unsubscribe(@channel) if @client.channel(@channel)?
|
156
|
+
|
157
|
+
|
158
|
+
class RenderSync.View
|
159
|
+
|
160
|
+
removed: false
|
161
|
+
|
162
|
+
constructor: (@$el, @name) ->
|
163
|
+
|
164
|
+
beforeUpdate: (html, data) -> @update(html)
|
165
|
+
|
166
|
+
afterUpdate: -> #noop
|
167
|
+
|
168
|
+
beforeInsert: ($el, data) -> @insert($el)
|
169
|
+
|
170
|
+
afterInsert: -> #noop
|
171
|
+
|
172
|
+
beforeRemove: -> @remove()
|
173
|
+
|
174
|
+
afterRemove: -> #noop
|
175
|
+
|
176
|
+
isRemoved: -> @removed
|
177
|
+
|
178
|
+
remove: ->
|
179
|
+
@$el.remove()
|
180
|
+
@$el = $()
|
181
|
+
@removed = true
|
182
|
+
@afterRemove()
|
183
|
+
|
184
|
+
|
185
|
+
bind: -> #noop
|
186
|
+
|
187
|
+
show: -> @$el.show()
|
188
|
+
|
189
|
+
update: (html) ->
|
190
|
+
$new = $($.trim(html))
|
191
|
+
@$el.replaceWith($new)
|
192
|
+
@$el = $new
|
193
|
+
@afterUpdate()
|
194
|
+
@bind()
|
195
|
+
|
196
|
+
|
197
|
+
insert: ($el) ->
|
198
|
+
@$el.replaceWith($el)
|
199
|
+
@$el = $el
|
200
|
+
@afterInsert()
|
201
|
+
@bind()
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
class RenderSync.Partial
|
206
|
+
|
207
|
+
attributes:
|
208
|
+
name: null
|
209
|
+
resourceName: null
|
210
|
+
resourceId: null
|
211
|
+
authToken: null
|
212
|
+
channelUpdate: null
|
213
|
+
channelDestroy: null
|
214
|
+
selectorStart: null
|
215
|
+
selectorEnd: null
|
216
|
+
refetch: false
|
217
|
+
|
218
|
+
subscriptionUpdate: null
|
219
|
+
subscriptionDestroy: null
|
220
|
+
|
221
|
+
# attributes
|
222
|
+
#
|
223
|
+
# name - The String name of the partial without leading underscore
|
224
|
+
# resourceName - The String undercored class name of the resource
|
225
|
+
# resourceId
|
226
|
+
# authToken - The String auth token for the partial
|
227
|
+
# channelUpdate - The String channel to listen for update publishes on
|
228
|
+
# channelDestroy - The String channel to listen for destroy publishes on
|
229
|
+
# selectorStart - The String selector to mark beginning in the DOM
|
230
|
+
# selectorEnd - The String selector to mark ending in the DOM
|
231
|
+
# refetch - The Boolean to refetch markup from server or receive markup
|
232
|
+
# from pubsub update. Default false.
|
233
|
+
#
|
234
|
+
constructor: (attributes = {}) ->
|
235
|
+
@[key] = attributes[key] ? defaultValue for key, defaultValue of @attributes
|
236
|
+
@$start = $("[data-sync-id='#{@selectorStart}']")
|
237
|
+
@$end = $("[data-sync-id='#{@selectorEnd}']")
|
238
|
+
@$el = @$start.nextUntil(@$end)
|
239
|
+
@view = new (RenderSync.viewClassFromPartialName(@name, @resourceName))(@$el, @name)
|
240
|
+
@adapter = RenderSync.adapter
|
241
|
+
|
242
|
+
|
243
|
+
subscribe: ->
|
244
|
+
@subscriptionUpdate = @adapter.subscribe @channelUpdate, (data) =>
|
245
|
+
if @refetch
|
246
|
+
@refetchFromServer (html) => @update(html)
|
247
|
+
else
|
248
|
+
@update(data.html)
|
249
|
+
|
250
|
+
@subscriptionDestroy = @adapter.subscribe @channelDestroy, => @remove()
|
251
|
+
|
252
|
+
|
253
|
+
update: (html) -> @view.beforeUpdate(html, {})
|
254
|
+
|
255
|
+
remove: ->
|
256
|
+
@view.beforeRemove()
|
257
|
+
@destroy() if @view.isRemoved()
|
258
|
+
|
259
|
+
|
260
|
+
insert: (html) ->
|
261
|
+
if @refetch
|
262
|
+
@refetchFromServer (html) => @view.beforeInsert($($.trim(html)), {})
|
263
|
+
else
|
264
|
+
@view.beforeInsert($($.trim(html)), {})
|
265
|
+
|
266
|
+
|
267
|
+
destroy: ->
|
268
|
+
@subscriptionUpdate.cancel()
|
269
|
+
@subscriptionDestroy.cancel()
|
270
|
+
@$start.remove()
|
271
|
+
@$end.remove()
|
272
|
+
@$el?.remove()
|
273
|
+
delete @$start
|
274
|
+
delete @$end
|
275
|
+
delete @$el
|
276
|
+
|
277
|
+
|
278
|
+
refetchFromServer: (callback) ->
|
279
|
+
$.ajax
|
280
|
+
type: "GET"
|
281
|
+
url: "/sync/refetch.json"
|
282
|
+
data:
|
283
|
+
auth_token: @authToken
|
284
|
+
partial_name: @name
|
285
|
+
resource_name: @resourceName
|
286
|
+
resource_id: @resourceId
|
287
|
+
success: (data) -> callback(data.html)
|
288
|
+
|
289
|
+
|
290
|
+
class RenderSync.PartialCreator
|
291
|
+
|
292
|
+
attributes:
|
293
|
+
name: null
|
294
|
+
resourceName: null
|
295
|
+
authToken: null
|
296
|
+
channel: null
|
297
|
+
selector: null
|
298
|
+
direction: 'append'
|
299
|
+
refetch: false
|
300
|
+
|
301
|
+
# attributes
|
302
|
+
#
|
303
|
+
# name - The String name of the partial without leading underscore
|
304
|
+
# resourceName - The String undercored class name of the resource
|
305
|
+
# channel - The String channel to listen for new publishes on
|
306
|
+
# selector - The String selector to find the element in the DOM
|
307
|
+
# direction - The String direction to insert. One of "append" or "prepend"
|
308
|
+
# refetch - The Boolean to refetch markup from server or receive markup
|
309
|
+
# from pubsub update. Default false.
|
310
|
+
#
|
311
|
+
constructor: (attributes = {}) ->
|
312
|
+
@[key] = attributes[key] ? defaultValue for key, defaultValue of @attributes
|
313
|
+
@$el = $("[data-sync-id='#{@selector}']")
|
314
|
+
@adapter = RenderSync.adapter
|
315
|
+
|
316
|
+
|
317
|
+
subscribe: ->
|
318
|
+
@adapter.subscribe @channel, (data) =>
|
319
|
+
@insert data.html,
|
320
|
+
data.resourceId,
|
321
|
+
data.authToken,
|
322
|
+
data.channelUpdate,
|
323
|
+
data.channelDestroy,
|
324
|
+
data.selectorStart,
|
325
|
+
data.selectorEnd
|
326
|
+
|
327
|
+
|
328
|
+
insertPlaceholder: (html) ->
|
329
|
+
switch @direction
|
330
|
+
when "append" then @$el.before(html)
|
331
|
+
when "prepend" then @$el.after(html)
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
insert: (html, resourceId, authToken, channelUpdate, channelDestroy, selectorStart, selectorEnd) ->
|
336
|
+
@insertPlaceholder """
|
337
|
+
<script type='text/javascript' data-sync-id='#{selectorStart}'></script>
|
338
|
+
<script type='text/javascript' data-sync-el-placeholder></script>
|
339
|
+
<script type='text/javascript' data-sync-id='#{selectorEnd}'></script>
|
340
|
+
"""
|
341
|
+
partial = new RenderSync.Partial(
|
342
|
+
name: @name
|
343
|
+
resourceName: @resourceName
|
344
|
+
resourceId: resourceId
|
345
|
+
authToken: authToken
|
346
|
+
channelUpdate: channelUpdate
|
347
|
+
channelDestroy: channelDestroy
|
348
|
+
selectorStart: selectorStart
|
349
|
+
selectorEnd: selectorEnd
|
350
|
+
refetch: @refetch
|
351
|
+
)
|
352
|
+
partial.subscribe()
|
353
|
+
partial.insert(html)
|
354
|
+
|
355
|
+
RenderSync.init()
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class RenderSync::RefetchesController < ApplicationController
|
2
|
+
|
3
|
+
before_filter :require_valid_request
|
4
|
+
before_filter :find_resource
|
5
|
+
before_filter :find_authorized_partial
|
6
|
+
|
7
|
+
def show
|
8
|
+
render json: {
|
9
|
+
html: with_format(:html){ @partial.render_to_string }
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def with_format(format, &block)
|
17
|
+
old_formats = formats
|
18
|
+
self.formats = [format]
|
19
|
+
block_value = block.call
|
20
|
+
self.formats = old_formats
|
21
|
+
|
22
|
+
block_value
|
23
|
+
end
|
24
|
+
|
25
|
+
def require_valid_request
|
26
|
+
render_bad_request unless request_valid?
|
27
|
+
end
|
28
|
+
|
29
|
+
def request_valid?
|
30
|
+
[
|
31
|
+
params[:resource_name],
|
32
|
+
params[:partial_name],
|
33
|
+
params[:auth_token]
|
34
|
+
].all?(&:present?)
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_resource
|
38
|
+
@resource = RenderSync::RefetchModel.find_by_class_name_and_id(
|
39
|
+
params[:resource_name],
|
40
|
+
params[:resource_id]
|
41
|
+
) || render_bad_request
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_authorized_partial
|
45
|
+
@partial = RenderSync::RefetchPartial.find_by_authorized_resource(
|
46
|
+
@resource,
|
47
|
+
params[:partial_name],
|
48
|
+
self,
|
49
|
+
params[:auth_token]
|
50
|
+
) || render_bad_request
|
51
|
+
end
|
52
|
+
|
53
|
+
def render_bad_request
|
54
|
+
head :bad_request
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RenderSync::ConfigHelper
|
2
|
+
def include_sync_config(opts = {})
|
3
|
+
return unless RenderSync.adapter
|
4
|
+
|
5
|
+
str = ''
|
6
|
+
|
7
|
+
unless opts[:skip_adapter]
|
8
|
+
str << %{<script src="#{RenderSync.adapter_javascript_url}" data-turbolinks-eval=false></script>}
|
9
|
+
end
|
10
|
+
|
11
|
+
str << %{<script data-turbolinks-eval=false>var RenderSyncConfig = #{RenderSync.config_json};</script>}
|
12
|
+
|
13
|
+
str.html_safe
|
14
|
+
end
|
15
|
+
end
|
data/config/routes.rb
ADDED
data/config/sync.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Faye
|
2
|
+
development:
|
3
|
+
server: "http://localhost:9292/faye"
|
4
|
+
adapter_javascript_url: "http://localhost:9292/faye/faye.js"
|
5
|
+
auth_token: "secret"
|
6
|
+
adapter: "Faye"
|
7
|
+
async: true
|
8
|
+
|
9
|
+
test:
|
10
|
+
server: "http://localhost:9292/faye"
|
11
|
+
adapter_javascript_url: "http://localhost:9292/faye/faye.js"
|
12
|
+
adapter: "Faye"
|
13
|
+
auth_token: "secret"
|
14
|
+
async: false
|
15
|
+
|
16
|
+
production:
|
17
|
+
server: "http://localhost:9292/faye"
|
18
|
+
adapter_javascript_url: "http://localhost:9292/faye/faye.js"
|
19
|
+
adapter: "Faye"
|
20
|
+
auth_token: "secret"
|
21
|
+
async: true
|