Skip to content

Commit ff53551

Browse files
committed
Initial version.
0 parents  commit ff53551

File tree

4 files changed

+399
-0
lines changed

4 files changed

+399
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.*
2+
.build*
3+
smart.lock

package.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Package.describe({
2+
summary: "Reactive server-side MongoDB queries",
3+
version: '0.1.0',
4+
name: 'peerlibrary:reactive-publish',
5+
git: 'https://github.com/peerlibrary/meteor-reactive-publish.git'
6+
});
7+
8+
Package.onUse(function (api) {
9+
api.versionsFrom('[email protected]');
10+
11+
// Core dependencies.
12+
api.use([
13+
'coffeescript',
14+
'underscore',
15+
'mongo'
16+
], 'server');
17+
18+
// 3rd party dependencies.
19+
api.use([
20+
'peerlibrary:[email protected]',
21+
'peerlibrary:[email protected]'
22+
], 'server');
23+
24+
api.addFiles([
25+
'server.coffee'
26+
], 'server');
27+
});
28+
29+
Package.onTest(function (api) {
30+
// Core dependencies.
31+
api.use([
32+
'tinytest',
33+
'test-helpers',
34+
'coffeescript',
35+
'insecure',
36+
'random',
37+
'underscore'
38+
]);
39+
40+
// Internal dependencies.
41+
api.use([
42+
'peerlibrary:reactive-publish'
43+
]);
44+
45+
api.add_files([
46+
'tests.coffee'
47+
]);
48+
});

server.coffee

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
originalPublish = Meteor.publish
2+
3+
Meteor.publish = (name, publishFunction) ->
4+
originalPublish name, (args...) ->
5+
publish = @
6+
7+
relatedPublish = null
8+
ready = false
9+
10+
publishDocuments = ->
11+
oldRelatedPublish = relatedPublish
12+
13+
Tracker.nonreactive =>
14+
relatedPublish = publish._recreate()
15+
16+
# We copy overridden methods if they exist
17+
for own key, value of publish when key in ['added', 'changed', 'removed', 'ready', 'stop', 'error']
18+
relatedPublish[key] = value
19+
20+
# If there are any extra fields which do not exist in recreated related publish
21+
# (because they were added by some other code), copy them over
22+
# TODO: This copies also @related, test how recursive @related works
23+
for own key, value of publish when key not of relatedPublish
24+
relatedPublish[key] = value
25+
26+
relatedPublishAdded = relatedPublish.added
27+
relatedPublish.added = (collectionName, id, fields) ->
28+
stringId = @_idFilter.idStringify id
29+
# If document as already present in oldRelatedPublish then we just set
30+
# relatedPublish's _documents and call changed to send updated fields
31+
# (Meteor sends only a diff).
32+
if oldRelatedPublish?._documents[collectionName]?[stringId]
33+
Meteor._ensure(@_documents, collectionName)[stringId] = true
34+
@changed collectionName, id, fields
35+
else
36+
relatedPublishAdded.call @, collectionName, id, fields
37+
38+
relatedPublish.ready = ->
39+
# Mark it as ready only the first time
40+
publish.ready() unless ready
41+
ready = true
42+
# To return nothing.
43+
return
44+
45+
relatedPublish.stop = (relatedChange) ->
46+
if relatedChange
47+
# We only deactivate (which calls stop callbacks as well) because we
48+
# have manually removed only documents which are not published again.
49+
@_deactivate()
50+
else
51+
# We do manually what would _stopSubscription do, but without
52+
# subscription handling. This should be done by the parent publish.
53+
@_removeAllDocuments()
54+
@_deactivate()
55+
publish.stop()
56+
# To return nothing.
57+
return
58+
59+
relatedPublish._handler = publishFunction
60+
relatedPublish._runHandler()
61+
62+
return unless oldRelatedPublish
63+
64+
Tracker.nonreactive =>
65+
# We remove those which are not published anymore
66+
for collectionName in _.keys(oldRelatedPublish._documents)
67+
for id in _.difference _.keys(oldRelatedPublish._documents[collectionName] or {}), _.keys(relatedPublish._documents[collectionName] or {})
68+
oldRelatedPublish.removed collectionName, id
69+
70+
oldRelatedPublish.stop true
71+
oldRelatedPublish = null
72+
73+
handle = Tracker.autorun (computation) =>
74+
publishDocuments()
75+
76+
publish.onStop ->
77+
handle?.stop()
78+
handle = null
79+
relatedPublish?.stop()
80+
relatedPublish = null
81+
82+
# To return nothing.
83+
return

0 commit comments

Comments
 (0)