[annotator-dev] Status of master, my work on Annotator mainline

Randall Leeds tilgovi at hypothes.is
Sat Dec 14 23:45:50 UTC 2013


The master branch has all green tests now.

It incorporates Nick's changes that started on the `wip` branch.
It incorporates my changes that started on the `browserify` branch.

My main goal in Annotator 2.0 is to increase code sharing between projects
using Annotator by making the core into a framework that can be more
readily adapted to different use cases and encouraging the community to
freely publish their own modules.

In preparation for our community call this week, here's an outline of what
I've done and why. Criticisms, praise, questions, etc all welcome.

E-mail gets long and dense after this point. Grab a cup of coffee. Close
the FaceSpace. Put on your thinking cap.

Registry
The Registry class has one simple function: coordinate discovery of
components and application bootstrapping. In the past, an Annotator was
created and then plugins were added to it. Some attempt has been made to
make removing plugins possible (via a `destroy()` method), but I believe
its safer and more robust to make explicit a separation between
configuration and run.

Core services
Using the new registry, I've created two core services: AnnotationProvider
and StorageProvider. The idea is that one can always find these on the
registry under the properties 'annotation' and 'store' respectively. This
way, one can write code which does not know which Store is being used, but
can still access it directly.

These first two changes should help eliminate the class of problem
exemplified by such issues as "Order of annotator plugins is important when
using Auth plugin" (https://github.com/okfn/annotator/issues/259).

The purpose of these services is to clearly label the public interfaces of
common components. With that, services can depend on and call one another
explicitly without needing to know the name of a specific class in the
Annotator.Plugin namespace, finding each other instead by service names
exported to a Registry instance. Example: `registry['store']` instead of
`plugins['Store']`.

Events
I've added the events, such as 'beforeAnnotationCreated', back into the
Annotator class as before. I would propose we discourage use of these by
plugins where there are better solutions. The major issue is that events
are assumed to be synchronously processed and often modify the annotation
data, but there are all kinds of reasons why this is bad.

As an example, consider the behavior of the existing Store plugin in
Annotator v1.2.x. It saves the annotation in response to
'annotationCreated'. But if the backend store is the source of truth then
the event really shouldn't fire until after the save happens. It is better
to explicitly invoke a the save process and defer the event until it is
finished. That is what the AnnotationProvider does, by calling the
StorageProvider. Now Annotator can wait until these asynchronous processes
are finished before firing the event. One can imagine an IdentityProvider
component which receives the request, pre-flight, from the StorageProvider
and adds the appropriate headers. With the structure I'm imagining, it
would be possible for the IdentityProvider to delay the create operation
until some asynchronous authentication process has completed.

With the old events still in place, old plugins should migrate with minimal
changes, but over time we can establish what the common components are and
what their interfaces are and promote them to services and export them to
the registry.

Browserify
The purpose of the browserify branch was to introduce a module system to
Annotator. There are three major reasons to do this.

The first is that it makes developing the Annotator code base easier. Our
Makefile has shrunk considerably (bookmarklet missing for the moment), our
source maps got better, and our test cases became more assuredly
independent.

As soon as we publish Annotator as an NPM module, it will be easy for users
of browserify or requirejs to include Annotator in their own projects.
Likely this will make it easy for someone to add bower support, too. If you
are not using a module system of any kind today, you may consider looking
at one of these.

The third and biggest gain from these changes comes from a combination of
the new Registry structure with the module system. I want to encourage us
all to publish modules independently. For example, right now someone who
wishes to use the threading plugin developed at Hypothes.is must pull the
source for it from our main repository. Someone wishing to use the
LOREStore plugin would have to pull it out of the plugins directory of the
UQ fork of Annotator. We could all contribute these to Annotator, but
that's centralizing the maintenance burden. The true strength of Open
Source lies in decentralizing. Let a hundred Annotation applications and
modules blossom.

I hope to see us all publishing more repositories, mixing and matching
extensions and library code from one another, and staying up to date with
mainline Annotator more easily.

Cheers
R
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.okfn.org/pipermail/annotator-dev/attachments/20131214/b72f4d5a/attachment-0003.html>


More information about the annotator-dev mailing list