Giter VIP home page Giter VIP logo

postal.js's People

Contributors

ajimix avatar arobson avatar avanderhoorn avatar dcneiner avatar dertseha avatar efurmantt avatar elijahmanor avatar gerhobbelt avatar ifandelse avatar jcreamer898 avatar jdalton avatar kamilbiela avatar kkirsche avatar rniemeyer avatar sergiopereiratt avatar stephenmathieson avatar travisthetechie avatar vernonk avatar webpro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

postal.js's Issues

Feature request: Durability

I've just come across a situation where durability has moved to the forefront.

In Durandal, often we compose views. The activate handler of a viewmodel is the best place to set up postal subscriptions. Many times, however, a parent view will publish a message to one or more of its children, but the child, or children, isn't ready yet.

It would be nice if messages could be marked "durable" so that when a subscriber subscribes, postal checks to see if there are any messages waiting for that subscriber (on that subscriber's channel and topic). Of course, we would need to be able to configure a timeout. One could even use postal.request-response and its promise to get back a fail after a timeout period. Another option could be to configure a timeout message to publish on some hard-coded channel and topic.

I solved the problem temporarily with a client-side queue. But this seems ideal for incorporation into postal--maybe not into core, but certainly as, say, postal.durable.

Dash as first character in topic

I've been using postal for a web app and discovered that if a dash leads off a topic in a subscription, the message is not received and the callback isn't fired.

Ex: abc.def.-ghi will not be called but

abc.def.ghi will be called.

unsubscribe call behaves unexpectedly

I'm trying to implement something like a one-time listener. However, unsubscribing at certain times behaves unexpectedly. Here's some code:

p = require 'postal'

postal = new p()

channel = postal.channel ''

subscription1 = channel.subscribe 'test', ->
  console.log '1 received message'

subscription2 = channel.subscribe 'test', ->
  console.log '2 received message'

channel.publish 'test'
subscription1.unsubscribe()
channel.publish 'test'

The above code behaves as expected, the output is as follows:

1 received message
2 received message
2 received message

However, to implement the "one-time" I did something like this:

p = require 'postal'

postal = new p()

channel = postal.channel ''

subscription1 = channel.subscribe 'test', ->
  console.log '1 received message'
  subscription1.unsubscribe()

subscription2 = channel.subscribe 'test', ->
  console.log '2 received message'

channel.publish 'test'
channel.publish 'test'

This outputs:

1 received message
2 received message

Which is pretty unexpected. Somehow the subscription1.unsubscribe() is unsubscribing both subscriptions.

Introduce the Strategy pattern for wildcard manipulation

I understand that one of the aims of postal was to support AMQP-style messages. But we may wish to utilize other formats. For example, I use a REST-like format:

channel: 'widgets/tabs/opportunities/e3abd555-e2cb-4db0-a5d1-c25ecbd5c1da'
topic: '/tab/project/data'

It's a great way to go for a lot of reasons. But, unfortunately, I'm unable to utilize the following:

topic: 'tab/#/data'

I wonder if wildcard manipulation should be strategized? Allow us to introduce our own binder resolver, in other words.

At a minimum, perhaps you could parameterize your RegEx expressions and allow them to be overridden.

It would seem, at present, that I need to replace the "/" with a ".".

Thank you.

does postal support IPC in node?

I need a pub/sub solution to use in node. Specifically I need to communicate between different node instances in different processes (IPC). Does postal support this without adding a separate engine like redis?

I would also like to communicate from the server to the client with the same pub/sub but that isn't a requirement since I'm already using socket.io. I am also interested in communicating between same-source windows in the browser which I think postal can do, right?

I find it strange that none of the zillion pub/sub solutions document whether they work across processes. Hook.io did but it no longer exists. Does everyone assume pub/sub is always just in one process?

getSubscribersFor(topic) doesn't return subscribers

I think getSubscribersFor(topic) should return an array of subscribers for the topic, at least according to the API page in the wiki. Unfortunately it doesn't. As the API page in the wiki is out of date too, I'm unsure if that behaviour is desired.

If this is really a bug I'd create a pull request with a fix.

Postal 0.8.2 CommonJS package broken

The following 2-liner, per the Postal docs, fails:

var postal = require('postal')
var defaultChannel = postal.channel();

Command output:

node postaltest.js

/Users/blah/postaltest.js:3
var defaultChannel = postal.channel();
                            ^
TypeError: Object function ( _ ) {
            _ = _ || require( "underscore" );
            return factory( _ );
        } has no method 'channel'
    at Object.<anonymous> (/Users/blah/postaltest.js:3:29)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:487:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

defer() and withDelay() don't pass envelope to callback

When configuring a subscription with defer() or withDelay(), the envelope parameter is not passed to the actual handler.

Is this intentional? I would have guessed it is passed on - at least the documentation on SubscriptionDefinition doesn't say otherwise.

clearUnSubQueue defined but never invoked - unsubscribe during publish() run will not work

From code review:
If I read the current HEAD rev code correctly at https://github.com/postaljs/postal.js/blob/master/src/LocalBus.js#L85 then any call to .unsubscribe() during a .publish() run is correctly queued (otherwise the cached queue length would become invalid), but the function called clearUnSubQueue in https://github.com/postaljs/postal.js/blob/master/src/LocalBus.js#L15 is defined but invoked nowhere, resulting in the unsubscribe queue filling up but never being executed.

(On a similar note, nobody is stopped from nesting .publish() calls so the global pubInProgress should not be set to true but instead be incremented and decremented, so that clearUnSubQueue() can be invoked at the end of outermost .publish().)

Problem with linkChannels

Uncaught TypeError: Object # has no method 'split' postal.min.js:7

postal.linkChannels(
{channel:"PlaylistManager" , topic: "tree.data.changed"},
{channel:"PlaylistTree" , topic:"data.changed"}
)

Consider using Grunt for QA/build

How about moving to Grunt for QA & build? Not that I have anything against Anvil, but that doesn't seem to be a very active project anymore, gave me an error, and Grunt is so widely used that it probably lowers the threshold to participate.

As far as I can see, Anvil is currently used in this project to concatenate and Uglify, run Testem(?), more..? I'd be more than happy to port that over and submit a PR.

Using wildcards when publishing messages?

I know it's possible to use wildcards when referencing topic names in the suscriptions. However, it does not seem possible to use wildcards to target multiple topics when publishing messages.

Am I doing something wrong or is it simply not supported?

Use of node modules...

So the build currently requires a global install of anvil. While not required, it would make more sense (to me) to have it more like...

  • build-all.sh: call into node_modules for anvil instead of calling an expected global anvil. Also check for existence and tell people to npm install if missing.
  • remove node_modules from the repo: just cleans up the repo, not a huge deal; remember package.json though
  • include npm install instructions in the README: This way people know explicitly what to do to get started. Also tell people that lib/*/postal.js is the compiled version. I didn't see that anywhere, did I just miss it?

This would make it all more 'node-ish' I think. Though sometimes I'll full of it, so maybe not :) Regardless, steps to make it less work and less impact on my system to get involved is a huge plus; thoughts?

NextVer: Remove minimal build option (?)

I'm not convinced having two builds of postal is worth the effort and potential confusion. Getting a custom lodash build seems much more worth the effort as far as minimizing overall file size footprint....

publish() doesn't fire when a hyphen is used in the topic string

I'm working on something that uses publish() to make components on the page aware of each others activity, and I use the HTML classes of those components to generate topic strings. The classes can contain hyphens, and I just discovered that publish() won't fire when the topic string contains a hyphen.

Is this a bug or an intended restriction? I couldn't find documentation about (un)allowed characters.

jsfiddle broken by 404 lodash.js link, Chrome/blink mime type error

Hello,

First of all thanks for postal.js and all the great articles you've written (here and at your blog(s)).

Fyi, the current jsfiddle that is linked to is busted because of a broken link to lodash. I created a new fiddle with an updated link to lodash (that's all I changed):
http://jsfiddle.net/FjDgK/1/

Additionally/unfortunately, it appears that Chrome's switch from webkit to blink has resulted in jsfiddle not working because of a mime type errors. (see screenshot)

screen shot 2013-09-07 at 7 20 05 pm

Integrating with Angular.js

We have an issue where when a callback is fired from a subscription we lose our $scopeiness. If we change something in scope we have to do a $scope.apply() around our changes that occur in the postal callback. This loses some of the magic in angular and I was wondering if there was way to intercept these and force them into the angular 'scope'. Maybe wrap the publish iterator with the $scope.apply (or a safeapply function that checks if we are in the apply scope already see https://coderwall.com/p/ngisma).

Using defer using setTimeout() doesn't work in IE7/8

We are using postal but are required to support IE7/8 and are running into problems with the defer method. The setTimeout signature in IE doesn't support the data parameter, so the message and envelope received by subscribers are always undefined. We've tried using a polyfill on the window object, but postal is calling setTimeout directly, skipping the polyfill.

Feature request: Two-way channels

A pattern has emerged in the development of my application where something like the following would be helpful:

postal.publish({
   channel: 'somechannel',
   topic: 'some.topic',
   request: {
      data: {}
   },
   response: {
      callback: function ( data, envelope ) {
      }
   }
});

In other words, if the publish contains request/response properties, then internally postal would publish using the two-way semantics. Otherwise, it would publish in the standard way.

On the flipside of the coin, elsewhere, we would have:

postal.subscribe({
   channel: 'somechannel',
   topic: 'some.topic',
   request: {
      callback: function ( data, envelope, response ) {
         doSomething();
         response.setData({});
      }
   },
   response: {
      data: {}
   }
});

The correlation between the two sides is that publish.request goes to subscribe.request, and subscribe.response goes to publish.response.

In the scenario above, response.setData() tells postal to respond on the same channel with the data as a payload, which the publisher would process in the normal way. Absent setData(), and static or precalculated data defined in the response block of the subscriber would be sent back, if desired.

One could even go so far as to add an "until" block to the publisher to allow a conditioned exchange of more than one request/response cycle, where publisher and subscriber continue to operate on the exchanged data object until a condition is met:

postal.publish({
   channel: 'somechannel',
   topic: 'some.topic',
   request: {
      data: {}
   },
   response: {
      callback: function ( data, envelope ) {
      }
   },
   until: {
      condition: function ( data, envelope ) {
         return data.count === 5;
      }
   }
});

We could still have a one-way subscriber to a two-way publisher:

postal.subscribe({
   channel: 'somechannel',
   topic: 'some.topic',   
   callback: function ( data, envelope) {
         doSomething();   
   }   
});

The subscriber above isn't involved in the response part.

Anyways, just a suggestion. I know it would make my life easier. Perhaps it would do so for others.

Thank you.

Node import instructions

There is a page on the wiki https://github.com/postaljs/postal.js/wiki/The-postal-object
that shows how to import postal in Node. Unfortunately, it doesn't work and gives the error: "TypeError: object is not a function"

I also found this old issue discussing how postal is imported #32

Looks like the import style changed at some point?
Also, are postal.xframe and postal.federation imported differently (still using the dependency injection style)?

Thanks for your help!

Request : Nuget Package Update & DefinitelyTyped for TypeScript

Firstly, Thanks very much for this great utility.

We noticed that the postal.js stays at version 0.90 on nuget.org. It will be great to have it updated to the latest.

The other thing we are wondering is if we can have a DefinitelyTyped file which will enable the postal.js to run under TypeScript language --- there is a growing trend of combination of angular.js & typescript, which brings Object Oriented power to angular. We assume there will be a bunch of guys who will need this cool utility running under TypeScript.

Best Wishes

postal.getSubscribersFor updates

The current getSubscribersFor method can find all subscribers for a given channel and topic. However, it will only look for exact matches to a topic binding (so if you subscribed with "some.topic.#", but you call getSubscribersFor and pass "some.topic.goodness", then the subscription you created with the wildcard binding will NOT be returned in the results.

I'm proposing we change this so that the topic you pass to getSubscribersFor gets compared to the subscription definition topic bindings via the bindingsResolver.

What say you @dcneiner @arobson @nicholascloud @estaylorco?

Conditional Subscriptions

Love postal! Best out there...

I have a suggestion: Conditional subscriptions, where the condition is based on some property value on the envelope.

Consider this example in pseudocode:

messagebus.addSubscription(topics.POPOVER_CLOSE, this.busContext, function(envelope) { close(envelope); } ).iif(envelope.target === 'globalActionsPopover')

or something to that effect.

I actually have a need for this as we speak. This is better, at least in this case, than having a topic per popover (which could run in the dozens or hundreds), and even better than hierarchical messages.

The subscription would still be registered with the bus, but it wouldn't event unless the criteria were satisfied. A fluent approach would allow for successive iif()'s.

Just a suggestion...

Binding Backbone.js events to a bus

So I've been thinking of ways to simplify binding of events in Backbone.js; I basically just want to find a way to describe what kind of message gets publishes or what topic. So my thought was using function proxies (http://wiki.ecmascript.org/doku.php?id=harmony%3aproxies#simulating_nosuchmethod_doesnotunderstand) that would inject some magic (model as data perhaps) to the message before it got published. Ideally it would just be...

var myview = Backbone.Views.extend({
   events: {
      "click input:submit": postalPublisher.myviewSubmittedCmd,
      "click input#doh": postalPublisher.navDismissPopupCmd
  }
})

Now I haven't done any proxying in JS before, so I have no idea if this works well in the browsers. I'm also open to other ideas to make this cleaner. This wouldn't really live inside postal, I don't think, but it's likely to be a generic enough implementation that it should be easy to just release as a bridge.

Sending emptying string as topic?

The current version of postal.js requires a topic value for postal.subscribe and postal.publish but does allow an empty string to be passed in.

A) is this intentional, and B) is the result of passing an empty topic string basically the equivalent of subscribing to a default topic for the given channel? (and if so, can't the topic argument just be made optional and if it is not manually passed in be automagically assigned to the default topic, e.g., mirroring the behavior of channels?)

Thanks

_ is undefined, but window._ is not

I'm having issues loading underscore through the postal.js initialization (first 10 lines or so of postal).

My page crashes as soon as postal tries to call _ , it comes in as undefined.
When debugging, I can tell that window._ at that point is available.

I have circumvented the issue for now by adding this to postal:

if (typeof _ === "undefined") {
var _ = window._;
}

I'm pretty sure I'm missing something here... any ideas or pointers?

Thanks!

Build fails

Wanted to play around with postal, but the build fails. I don't need it to run the tests, but I'd also like to test the built version. Does the output below look familiar, any ideas?

$ npm install anvil.js -g
$ anvil
starting activity, pre-build
    plugin: 'anvil.build-task-runner'
starting activity, identify
    plugin: 'anvil.identify'
[...]
Uglifying 1 files
starting activity, push
    plugin: 'anvil.headers'
    plugin: 'anvil.output'
starting activity, test
    plugin: 'anvil.testem'
 error running activity test : Error: bindAll must be passed function names
Error: bindAll must be passed function names
    at Function._.bindAll (/Users/lars/.anvilextensions/node_modules/anvil.testem/node_modules/testem/node_modules/underscore/underscore.js:628:35)
    at new Api (/Users/lars/.anvilextensions/node_modules/anvil.testem/node_modules/testem/lib/api.js:51:7)
    at anvil.plugin.run (/Users/lars/.anvilextensions/node_modules/anvil.testem/lib/testem.js:45:22)
    at /usr/local/lib/node_modules/anvil.js/lib/activityManager.js:104:21
    at iterate (/usr/local/lib/node_modules/anvil.js/lib/scheduler.js:68:24)
    at Scheduler.pipeline (/usr/local/lib/node_modules/anvil.js/lib/scheduler.js:83:4)
    at activityManager.runActivity (/usr/local/lib/node_modules/anvil.js/lib/activityManager.js:62:21)
    at Fsm.transition (/usr/local/lib/node_modules/anvil.js/node_modules/machina/lib/node/machina.js:118:35)
    at done (/usr/local/lib/node_modules/anvil.js/lib/activityManager.js:57:13)
    at done (/usr/local/lib/node_modules/anvil.js/lib/scheduler.js:74:6)

.jshint and .jsbeautifyrc for contribution?

I'd like to contribute, but I would like to so so with common understandings regarding code quality and format. .jshintrc and .jsbeautifyrc files are great for this, because then these things can be ensured by tools. I could do without, but most likely I won't get the format consistent.

Would you be open for such an addition to the project? Do you have preferences? I could provide some sensible settings, but I guess there might be minor changes here and there, so better be reformatted by the project rather than some random new guy :)

Request for additional utils

Hello All:

I am in the process of replacing the use of Durandal's pub/sub with postal, and based on my design pattern, the following utils would be useful:

utils.unsubscribeAllOver( topic )
utils.unsubscribeAllOn( channel )
utils.unsubscribeAllFor( channel, topic )

This would facilitate the top-level approach to using postal (i.e. where one does not need to hang onto a channel definition). Currently, the problem is that one still has to hang onto something in order to unsubscribe. I typically have two functions in my modules: registerSubscriptions() and unregisterSubscriptions(), where I might be [un]registering 5 or 10 subscriptions.

Currently, unless I'm missing something in postal, I have to create an Array in the module, push the subscriptions, and then for-each the array to unsubscribe each.

Do the above utils make sense?

Thank you.

Consider to run specs over concatenated build (> noConflict)

When I wanted to create a spec for the new noConflict() feature, I noticed that's impossible to test without the concatenated build (which has the src/postal.js wrapper file), since that's where postal is assigned to root/window.

So that gives us three options:

  1. Not implement the feature.
  2. Implemented the feature without specs.
  3. Refactor the specs to target the concatenated build (instead of directly sources).

On a related note, this feature would be a great help in order to be able to start creating benchmarks (#56) and compare changes performance-wise.

Looking forward to your feedback.

Node.js performance

I'm not being able to think of performance benchmark tests for node.js. It would be nice to have a benchmark to see how well this lib perform in ops/sec. Benchmark.js would be enough I guess, but I don't have enough knowledge on this module to create those tests

Feature request: Store the wildcard part on the envelope

I've encountered three situations where it was necessary to pull out the wildcard portion ("*" or "#") of a topic. It's easy enough with JavaScript's string manipulation toolbox.

But it would be nice if that information were available on the envelope.

For example, imagine a subscription to topic '/tab/#/selected'. A message is received over the topic '/tab/projects/selected'. It would be helpful if I could simply gain access to the wildcarded portion with envelope.wildcard, which in this case would return 'projects'.

I haven't checked to see if postal supports multiple wildcards. If so, then an array would have to be returned listing the wildcards in order of their appearance.

Does this make sense?

Memory Leak on Queued Unsubscribe

Unsubscribe calls are queued to occur after the publish is completed. That's a good thing, but the current implementation causes a memory leak.

101 SubscriptionDefinition.prototype = {
102 unsubscribe : function () {
103 if ( !this.inactive ) {
104 this.inactive = true;
105 postal.configuration.bus.unsubscribe( this );
106

344 unsubscribe : function ( config ) {
345 if ( pubInProgress ) {
346 unSubQueue.push( config );
347 return;
348 }
349 if ( this.subscriptions[config.channel][config.topic] ) {
350 var len = this.subscriptions[config.channel][config.topic].length,
351 idx = 0;
352 while ( idx < len ) {
353 if ( this.subscriptions[config.channel][config.topic][idx] === config ) {
354 this.subscriptions[config.channel][config.topic].splice( idx, 1 );
355 break;
356 }
357 idx += 1;
358 }
359 }
360 }

On unsubscribe, line 102 is executed. Note that we set the inactive flag on line 104. The local bus unsubscribe is then called and we execute line 344. Since the publish is in progress, the subscription is queued up on line 346. Note that the code at 349 is not executed. So far so good.

When the queued subscription is later unsubscribed, line 102 is again executed. However, now that the inactive flag is true, the unsubscribe for the local bus is never called. This means line 354 is never executed, keeping the subscription in the array forever.

If you later call postal.getSubscribersFor(channel, topic) you can see the subscriptions never decreasing even though unsubscribe has been called

latest postal broken in IE 8-9

line 410

postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc )

will not work in IE 8-9

Object.prototype.hasOwnProperty.call(postal.configuration.bus.subscriptions[ channel ], tpc);

this is the same fix that that you made for postal-federation

TypeError: Object function ( _ ) on require in Node

I'm experiencing the following error when attempting to use Postal in Node 0.10

App.js

var channel = postal.channel();

Error

TypeError: Object function ( _ ) {
            _ = _ || require( "underscore" );
            return factory( _ );
        } has no method 'channel'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.