Pelle Wessman – English posts2019-11-13T16:07:20+00:00https://voxpelli.com/english.xmlPelle Wessman[email protected]How to use TypeScript 3.7 to generate declarations from JSDoc2019-10-07T15:42:27+00:00http://voxpelli.com/2019/10/use-type-script-3-7-to-generate<h2 id="background">Background</h2>
<p>While TypeScript for long has supported validating the types in ones javascript files, even reading ones JSDoc-comments, it hasn’t really worked that well for those who in turn wanted to use ones code.</p>
<p>By default TypeScript doesn’t read the JSDoc of any dependencies. One have had to set <code class="highlighter-rouge">maxNodeModuleJsDepth</code> to a higher value, which hasn’t been without some issues.</p>
<p>Issues range from having the required depth change over time due to nested modules in <code class="highlighter-rouge">node\_modules</code>, making it hard to guarantee that types has been read, and picking up weird JSDoc comments from other packages – JSDoc comments that has never been tested for correctness.</p>
<p>So, what about <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/">TypeScript 3.7</a>? It <a href="https://github.com/microsoft/TypeScript/pull/32372">introduces a way</a> to create a type definition file from your JSDoc definitions. I decided to try it out on a project.</p>
<h2 id="how-to">How-to</h2>
<p>This is how I added it to a project which publishes a single <code class="highlighter-rouge">index.js</code> file, <a href="https://github.com/voxpelli/node-bunyan-adaptor">bunyan-adaptor</a>:</p>
<h3 id="1-create-a-new-tsconfig-file">1. Create a new tsconfig file</h3>
<p>Add a new <code class="highlighter-rouge">tsconfig.json</code> with the sole purpose of generating your declaration. This way you can avoid getting declarations generated for tests and such.</p>
<p>I added a <code class="highlighter-rouge">declaration.tsconfig.json</code> containing:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"extends": "./tsconfig",
"exclude": [
"test/**/*.js"
],
"compilerOptions": {
"declaration": true,
"noEmit": false,
"emitDeclarationOnly": true
}
}
</code></pre></div></div>
<h3 id="2-add-a-npm-script-for-generating-the-declaration">2. Add a npm script for generating the declaration</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"declaration:build": "rm -f index.d.ts && tsc -p declaration.tsconfig.json",
</code></pre></div></div>
<h3 id="3-optional-add-a-npm-script-for-ensuring-your-declaration-has-been-committed">3. (optional) Add a npm script for ensuring your declaration has been committed</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"declaration:check": "git diff --exit-code -- index.d.ts",
</code></pre></div></div>
<h3 id="4-optional-add-a-prepublishonly-npm-script">4. (optional) Add a prepublishOnly npm script</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"prepublishOnly": "npm run --silent declaration:build && npm run --silent declaration:check",
</code></pre></div></div>
<p>Or simpler, with the use of <a href="https://github.com/mysticatea/npm-run-all">npm-run-all</a>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"prepublishOnly": "run-s declaration:*",
</code></pre></div></div>
<h3 id="5-profit--party----">5. Profit / Party / 🦄 / 🤳</h3>
<p>However you want to celebrate: This is the moment.</p>
<p>Run <code class="highlighter-rouge">npm run declaration:build</code>, commit the resulting <code class="highlighter-rouge">index.d.ts</code> and publish your module!</p>
<p><strong>Note:</strong> Visual Studio Code could/will complain about your generated type declaration unless you tell it to use TypeScript 3.7.</p>
<p>Tell it by running the <code class="highlighter-rouge">TypeScript: Select TypeScript Version...</code> command when in eg. the type declaration file.</p>
3 tricks to better handle npm modules2016-07-05T17:10:00+00:00http://voxpelli.com/2016/07/better-handle-npm-modules<p>Developing with npm modules isn’t just installing modules and then updating them. In a team environment you might not even know when a new module should be installed or when its version requirement has changed. This can cause lots of weird unexpected behaviors when the installed modules doesn’t match the expectations of the app – and that annoys and is a waste of time.</p>
<p>Here I’ll give you three tricks to avoid that. Tricks which I’ve begun to use over the years and which we’re currently using at my latest project, the development of the new sites for <a href="http://www.sydsvenskan.se/">Sydsvenskan</a> and <a href="http://www.hd.se/">HD</a>.</p>
<h2 id="1-verify-installed-versions-against-packagejson">1. Verify installed versions against package.json</h2>
<p>When rapidly developing a new site, establishing the basic features etc, new modules gets added quite a lot. Often after a rebase one realize that one is missing a module after ones <a href="http://nodemon.io/">nodemon</a> process suddenly crash with some unexpected weird error.</p>
<p>I created <a href="https://github.com/voxpelli/node-installed-check">installed-check</a> to solve that. To have a script I could run to check if my installed modules still fulfilled the requirements set out by the package.json or whether it was time to install some more. All checked locally, without any slow network lookups or such.</p>
<p>If any module were missing or were outside the version requirements it would exit with an error.</p>
<p>I then hooked that script into my <code class="highlighter-rouge">npm test</code> script and into <a href="https://github.com/typicode/husky">husky</a> (at <code class="highlighter-rouge">postapplypatch</code> and <code class="highlighter-rouge">postmerge</code>) so that whenever I pulled down new code or ran my tests it verified that my installation was up to date.</p>
<p>With that in place everyone in the team could stop worry about whether they were missing a module locally and we could all stop wasting time debugging issues that were due to changes in the package.json requirements. Happy developers!</p>
<h2 id="2-verify-that-packagejson-is-in-sync-with-actual-module-usage">2. Verify that package.json is in sync with actual module usage</h2>
<p>While tests may pass just fine locally, if one doesn’t commit all the dependency requirements then it’s hard for them to pass anywhere else.</p>
<p>Likewise refactored code may work just fine, but one may not have realized that a removed <code class="highlighter-rouge">require()</code> was the very last one for a given module.</p>
<p>Therefore I always run <a href="https://github.com/maxogden/dependency-check">dependency-check</a> (which I now co-maintain) in my <code class="highlighter-rouge">npm test</code>. To ensure that uncommitted dependencies are caught early and that no extra modules are kept around and weighing down the project after they are no longer in use.</p>
<p>I also make <code class="highlighter-rouge">npm test</code> run before code is pushed remotely by setting up a <code class="highlighter-rouge">prepush</code> git hook using <a href="https://github.com/typicode/husky">husky</a>. That way neither I or anyone else in the team can accidentally push code with any such mistakes. (I’ve found <code class="highlighter-rouge">prepush</code> to work better for this than <code class="highlighter-rouge">precommit</code> – more pragmatic, with happier developers as a result)</p>
<h2 id="3-verify-engine-requirements-of-installed-modules">3. Verify engine requirements of installed modules</h2>
<p>How do you express what versions of node.js your library supports? There’s the <a href="https://docs.npmjs.com/files/package.json#engines">engines field</a> in package.json for that:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s2">"engines"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"node"</span><span class="p">:</span><span class="w"> </span><span class="s2">">=5.0.0"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Simple. You know what engine you support and you politely tell others so that they easily can find out as well.</p>
<p>But how do you detect when others update their requirements and how do you avoid that you get dependencies that have stricter engine requirements than you yourself have? Surely there must be able to verify that automatically?</p>
<p>Check out the just released <code class="highlighter-rouge">2.0.0</code> version of <a href="https://github.com/voxpelli/node-installed-check">installed-check</a>: It has a new optional flag, <code class="highlighter-rouge">--engine-check</code>, that makes it also check the engine requirements of all of the installed dependencies.</p>
<p>If the engine requirements of any installed dependencies doesn’t match yours, then an error will be returned along with a suggestion of a stricter engine requirement whenever possible.</p>
<p>By running that in your <code class="highlighter-rouge">npm test</code> you can easily early detect whenever an engine requirement change and either avoid the change altogether or move along with it and release a new major version yourself with the new stricter engine requirements. (Changed engine requirements are always to be considered a breaking change, which requires a new major version according to <a href="http://semver.org/">Semantic Versioning</a>)</p>
<p>Only gotcha with this approach is that not all modules explicitly define their engine requirements in their package.json. By default installed-check ignores any such modules and doesn’t treat undefined engine requirements as an error. By setting either or both of the <code class="highlighter-rouge">--verbose</code> and <code class="highlighter-rouge">--strict</code> flags one can make it warn or throw errors whenever it encounters such a module though.</p>
<h2 id="example-run-all-the-tricks">Example: Run all the tricks</h2>
<p>Install the modules:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install</span> <span class="nt">--save-dev</span> installed-check
npm <span class="nb">install</span> <span class="nt">--save-dev</span> dependency-check
npm <span class="nb">install</span> <span class="nt">--save-dev</span> husky
</code></pre></div></div>
<p>Set them up to run:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"scripts"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"installed-check -e && dependency-check . && dependency-check . --extra --no-dev"</span><span class="p">,</span><span class="w">
</span><span class="s2">"prepush"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm test"</span><span class="p">,</span><span class="w">
</span><span class="s2">"postapplypatch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"installed-check -e"</span><span class="p">,</span><span class="w">
</span><span class="s2">"postmerge"</span><span class="p">:</span><span class="w"> </span><span class="s2">"installed-check -e"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Then profit from a more solid dependency workflow and a more happy development team!</p>
Experts don’t change the world, society does2016-03-13T13:50:00+00:00http://voxpelli.com/2016/03/experts-dont-change-the-world<p>The expert. The pinnacle of knowledge within a field. The Einstein. The one who pushes the boundaries of humanities to new heights. The true revolutionary. The one everyone wants to be. The one everyone strives to become.</p>
<p>Or?</p>
<p>The expert truly knows a lot. But the expert mostly knows a lot about something in particular. It understands a field very well and knows how to solve problems and push things forward within that field.</p>
<p>But what about other fields? Does the expert also necessarily knows a lot about the other fields that it interacts with? Is the expert also an expert in integrating it’s solution into the wider context of society?</p>
<p>There’s many types of knowledge. There’s everything from the deep knowledge within a narrow field to the wider, more shallow knowledge across a range of fields. Any kind on it’s own doesn’t change the world, but when they interface with each other and leverages one another, that’s when true change can occur.</p>
<p>By worshipping the expert, the specialist, as the one to change the world, we neglect the necessity of, and the power that comes with, a wider understanding of knowledge.</p>
<p>It’s when society works together to tackle challenges as one, and when the knowledge of a wide range of disciplines and kinds are combined, that true powerful change is achieved.</p>
<p>When through the power of generalists the knowledge of experts are combined. That’s when society truly shines.</p>
My 2015 in Summary2016-03-13T10:00:00+00:00http://voxpelli.com/2016/03/my-2015-in-summary<p>2016 is in full swing and it’s long overdue to take a look back at the past year and what happened then. This is the final part of this four part series of posts about 2015.</p>
<h3 id="tldr">tl;dr</h3>
<p>The year started out at Bloglovin, but I later left and now I freelance. Throughout I built some cool stuff for both Bloglovin (push, better images, smarter feed) and the IndieWeb (publishing to Jekyll blogs from eg. iOS etc) and now I’m all occupied building cool stuff as a freelancer.</p>
<h3 id="a-list-of-all-new-projects-2015">A list of all new projects 2015</h3>
<ul>
<li><a href="https://github.com/bloglovin/metadataparser">Metadataparser</a> – Node.js module, Bloglovin-related of which I currently have a <a href="https://github.com/voxpelli/metadataparser/">personal fork</a></li>
<li><a href="https://github.com/voxpelli/node-promised-retry">Promised Retry</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-pg-pubsub">PG Pubsub</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-fetch-politely">Fetch Politely</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-micropub-express">Micropub Express</a> – Node.js module, IndieWeb-related</li>
<li><a href="https://github.com/voxpelli/node-format-microformat">Format Microformat</a> – Node.js module, IndieWeb-related</li>
<li><a href="https://github.com/voxpelli/node-github-publish">GitHub Publish</a> – Node.js module</li>
<li>and some other projects that I have yet to polish some more on as well as eg. the above mentioned workflows for Workflow.app and Editorial.app that isn’t really standalone projects of their own</li>
</ul>
<h3 id="a-list-of-updated-projects-2015">A list of updated projects 2015</h3>
<ul>
<li><a href="https://github.com/voxpelli/lintlovin">Lintlovin</a> – Node.js module, a personal fork of mine which is upgraded to eg. use ESLint</li>
<li><a href="https://webmention.herokuapp.com/">A WebMention Endpoint</a> – hosted service written in Node.js</li>
<li><a href="https://github.com/voxpelli/node-connect-pg-simple">Connect PG Simple</a> – Node.js module – probably my smallest and most popular project with certainly the highest amount of contributors (GitHub currently says <a href="https://github.com/voxpelli/node-connect-pg-simple/graphs/contributors">8 other persons</a> have contributed to it)</li>
<li>and some other projects as well as a <a href="https://github.com/issues?utf8=%E2%9C%93&q=author%3Avoxpelli+is%3Apr++created%3A2015-01-01..2015-12-31+">bunch of PR:s</a> that’s been contributed to a bunch of projects – such as <a href="https://github.com/maxogden/dependency-check">Dependency Check</a>.</li>
</ul>
<h3 id="a-list-of-all-posts-in-this-series">A list of all posts in this series</h3>
<ul>
<li>Part 1: My 2015 in Startup</li>
<li>Part 2: My 2015 in IndieWeb</li>
<li>Part 3: My 2015 in Freelance</li>
<li>and this post as the final part</li>
</ul>
My 2015 in IndieWeb2016-03-12T15:55:00+00:00http://voxpelli.com/2016/03/my-2015-in-indieweb<p>2016 is in full swing and it’s long overdue to take a look back at the past year and what happened then. This is <strong>part two of four</strong> in a series of posts about 2015.</p>
<h3 id="the-summer">The summer</h3>
<p>For the remainder of the summer, after I had <a href="/2016/03/my-2015-in-startup/">left Bloglovin</a>, I decided to take a long vacation, or as Chris Messina puts it: a ”<a href="https://medium.com/@chrismessina/funemployed-153b2e691a4e#.kytskxorc">funemployment</a>”. Reading books in the sun during the day and coding IndieWeb in the nights.</p>
<p>Lots of interesting IndieWeb experiments therefore happened during the summer, that pushed me closer to being able to have a more complete IndieWeb experience at this site.</p>
<h3 id="micropub--the-missing-piece">Micropub – the missing piece</h3>
<p>First and largest of those experiments was my decision to finally tackle the main challenge I have had in participating in the Indieweb: The fact that this blog is a <a href="https://github.com/voxpelli/voxpelli.github.com">static</a> <a href="http://jekyllrb.com/">Jekyll</a> based <a href="https://pages.github.com/">GitHub Pages</a> site.</p>
<p>The static nature of course means that I can’t do anything dynamic on the server side and with the ethos in the IndieWeb world (and beyond) being that websites should be <a href="https://indiewebcamp.com/curlable">curlable</a> it has been a challenge to add anything but non-original content such as <a href="https://webmention.herokuapp.com/">WebMentions</a> to it.</p>
<p>I therefore decided to look into the feasibility of making a separate service which could accept instructions to add or modify original content on my site and perform the commits to my site that it needed to carry out those instructions.</p>
<p>With <a href="http://indiewebcamp.com/micropub">Micropub</a> becoming the standard API within the IndieWeb community for such type of instructions I went on to create a bridge between that and the GitHub CRUD API. I created three different Node.js modules through which I got an <a href="https://github.com/voxpelli/node-micropub-express">interface for Micropub requests</a>, <a href="https://github.com/voxpelli/node-format-microformat">a transformation of it</a> into the files I need to commit and a simple <a href="https://github.com/voxpelli/node-github-publish/">module for commiting those</a> to my repository.</p>
<p>By connecting those I got a service with which I could finally accept posts to my blog from tools like <a href="http://ownyourgram.com/">OwnYourGram</a> and <a href="https://quill.p3k.io">Quill</a>. I even got support for uploading images and videos that are part of those posts.</p>
<p>My <a href="https://github.com/voxpelli/voxpelli.github.com">Jekyll theme</a> also got extended so that it could present the now much more rich posts in an appropriate way, through some more <a href="https://github.com/voxpelli/voxpelli.github.com/blob/master/_includes/post.html">complex templating</a>, and I also added two new lists on my site, <a href="http://voxpelli.com/links/">Links</a> and <a href="http://voxpelli.com/social/">Social</a>, so any non-blog content had somewhere to go.</p>
<p>I’ve yet to polish the glue that binds the three modules into a service and the Jekyll templates that renders the posts. When I have they will be released as their own projects as well.</p>
<h3 id="ios--the-dogfeeding">iOS – the dogfeeding</h3>
<p>With the publishing working I went on to look for useful ways of using it. Since I had been intrigued by the <a href="https://www.macstories.net/ios/instapaper-launches-notes-bringing-annotations-to-articles/">Instapaper annotations flow</a> that <a href="https://twitter.com/viticci">Federico</a> of <a href="https://www.macstories.net/">MacStories</a> had described for the <a href="http://omz-software.com/editorial/">Editorial app</a> in <a href="https://www.macstories.net/reviews/editorial-1-2-brings-powerful-new-text-editing-features-more-ios-automation/">some articles</a> I couldn’t resist trying to adapt it to my new Micropub endpoint so that I could start publishing my own annotations in an IndieWeb <a href="https://indiewebcamp.com/selfdogfood">selfdogfeeding</a> way.</p>
<p>That meant I had to create a Micropub client for the Editorial app, but thanks to the amazing Python integration that Editorial.app has, I pretty soon had a rough version of such a client up an running.</p>
<p>I recorded some screencasts showing the Editorial flows in practise. Here’s one for publishing said Instapaper annotations to my <a href="http://voxpelli.com/links/">Links</a> section on my blog (sorry for the silent sound):</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/U7hUR7flTAY" frameborder="0" allowfullscreen=""></iframe>
<p>It uses the three Editorial workflows: <a href="http://www.editorial-workflows.com/workflow/5833229495959552/tO76Z7cIfTU">Micropub</a>, <a href="http://www.editorial-workflows.com/workflow/5227209878929408/JZrTPYnXAiY">IndieAuth</a> and optionally, if one wants to re-authenticate, <a href="http://www.editorial-workflows.com/workflow/5300464841129984/cghZUwlSP2k">IndieAuth Deauthorize</a>.</p>
<p>I later extended my main flow with more metadata + added a flow for replying to posts from within a browser through a new <a href="https://workflow.is/workflows/581bf69b9cce48129bb2628a7ddea67f">Workflow.app workflow</a> and <a href="http://www.editorial-workflows.com/workflow/5272002294185984/FjNSs8nDyBs">Editorial workflow</a>. Here’s an updated screencast showing that in practice:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/CBPmSpD2jN4" frameborder="0" allowfullscreen=""></iframe>
<p>I also created a <a href="https://workflow.is/workflows/0f7b503f16ca4709a43a55e00b4c71b2">Workflow.app workflow</a> for publishing a bookmark (with an optional quote from the selection on a page in a browser), reusing the same <a href="http://www.editorial-workflows.com/workflow/5272002294185984/FjNSs8nDyBs">IndieAction Editorial workflow</a> as the reply flow did.</p>
<p>So – from at the start of the summer not being able to programmatically publish anything to my blog I could at the end of the summer both publish posts with images and video and publish posts from iOS. I could even reply to posts from within a browser. That’s pretty cool. Happy that I had time to finally overcome the obstacle and imagining that it can open up some new possibilities going forward.</p>
<h3 id="my-blog--nearly-indieweb-ready">My blog – nearly IndieWeb ready</h3>
<p>With Micropub support done my blog now nearly supports all the most important aspects of an IndieWeb:ish site. All that’s missing before I feel that I can say that it is fully IndieWeb ready is automatic WebMention <em>sending</em>. That has proved a bit problematic for static sites as there’s often a delay between publishing something and it being published, as the site has to be built. One therefore has to wait with the Webmention pinging until one knows that the update has actually been published., which requires some special mechanisms. I have some ideas for that as well and some tools have also started to emerge within the IndieWeb community so I hope that in 2016 I will have that little last piece of the puzzle solved.</p>
<h3 id="webmentions--a-status-update">Webmentions – a status update</h3>
<p>Micropub wasn’t the only IndieWeb project I worked on in 2015. I of course also worked on my <a href="http://webmention.herokuapp.com/">Webmentions project</a> which for long has been my main IndieWeb project.</p>
<p>In 2015 I released a bunch of new features and tweaks to my Webmention project, such as:</p>
<ul>
<li>At the very beginning of the year a new experimental embed, <em>”cutting-edge”</em>, was introduced to allow for new UI-additions without breaking existing embeds. With the initial release a <a href="http://indiewebcamp.com/facepile">facepiles</a> was added and all <a href="http://indiewebcamp.com/interactions">interactions</a> such as like and repost was moved there.</li>
<li>Basic support for updates as well as some deletes of mentions was finally introduced – fully realtime for some embeds. So now any awkward misspellings etc. can be quickly and swiftly fixed. Full delete support is being tracked in <a href="https://github.com/voxpelli/webpage-webmentions/issues/5">issue #5</a>.</li>
<li>I extracted the <a href="https://github.com/voxpelli/node-pg-pubsub">PG Pubsub</a> from the realtime solution and <a href="http://voxpelli.com/2015/01/pubsub-with-postgres-and-node-js/">launched it</a> as <a href="https://github.com/voxpelli/node-pg-pubsub">a separate module</a> so it can help fulfill Postgres Pubsub needs in other projects as well. As part of that I also launched <a href="https://github.com/voxpelli/node-promised-retry">Promised Retry</a> as a generic Promised based wrapper and retry mechanism that ensures that something like a working database connection is always returned to the caller, even if the original connection has been lost and a retry has to be made.</li>
<li>I also extracted the code responsible for ensuring that all web pages fetched are fetched ”politely” (rate limited) and combined that with an optional robots.txt mechanism extracted from my <a href="https://github.com/voxpelli/relspider">relspider</a> project and launched that as a combined module called <a href="https://github.com/voxpelli/node-fetch-politely">Fetch Politely</a> so that ultimately both my projects as well as those of others can utilize the same basic polite fetching mechanics. I also added a new optional database backend to the module, which I began using in the Webmentions project to ensure that any throttled fetches was persisted and shared beyond the life of a single instance, which in turn made me relax the mechanisms around eventually rejecting source URL:s from a domain that’s flooded with requests.</li>
<li>As with most of my projects I moved to iojs and then later Node.js 4.x and 5.x to get newer features like arrow functions and native Promises. I still don’t do eg. Babel, especially not server side.</li>
<li>In the later part of the year yet I added yet another new embed option. This one solved the <a href="https://indiewebcamp.com/curlability">curlability</a> problem of the original two embeds by moving to a progressively enhanced curlable link (identified by experimental microformat class <em>”u-responses”</em>). This enabled eg. evenntually supporting <a href="http://indiewebcamp.com/Salmentions">Salmentions</a>. As a consequence of rendering more things server side due to this I also decided to move the project to my <a href="https://github.com/voxpelli/node-tema">Tema</a> theme engine to get an improved server side templating solution that’s also shared with my other projects and can eg. enable new themes to be created for the project, which opens up some new possibilities.</li>
<li>A full <a href="http://indiewebcamp.com/Salmentions">Salmentions</a> flow was also added, but not released. It receives comments from downstream, presents them and repings them upstream. As part of this I again stumbled upon the amazingness of Postgres by being able to <a href="https://github.com/voxpelli/webpage-webmentions/blob/05012a5f400a98aa2c8e3079ccbebec84d6f080c/lib/classes/entries.js#L284">recursively fetch</a> the comment tree, no matter how deep it was, through the use of <a href="http://www.postgresql.org/docs/8.4/static/queries-with.html"><em>”WITH RECURSIVE”</em></a>. The current implementation of Salmentions is yet a bit too optimistic to be released. It repings upstream no matter if a mention has changed or not, which means quite some excessive pings and maube even in the worst case scenario an infinite sequence of circular pings. I therefore plan to add some kind of check whether a post has been updated or not before launch. That and other Salmentions issues is being tracked in <a href="https://github.com/voxpelli/webpage-webmentions/issues/21">issue #21</a>.</li>
<li>As part of the Salmentions feature I also moved the parsing of pages to an <a href="https://github.com/voxpelli/metadataparser/">extendable fork</a> of the <a href="https://github.com/bloglovin/metadataparser">Metadataparser</a> module that I had made at Bloglovin previously in the year. But with added in Microformats parsing for this project of coruse.</li>
</ul>
<p>All changes in my Webmention project in 2015 can be found in its <a href="https://github.com/voxpelli/webpage-webmentions#changelog">changelog</a> and one can also <a href="https://github.com/voxpelli/webpage-webmentions/releases.atom">subscribe to releases</a> to get notified about changes as they are released.</p>
<h3 id="the-future">The future</h3>
<p>In 2016 I plan to wrap up my Micropub setup and release all of the code related to it as reusable compontents. I also hope to finalize Salmentions support in my Webmention project and to get my blog to actually start sending Webmentions itself so that the full circle of Reply -> Notification -> Reply starts to work for me.</p>
<p>In the nearest future I will do a presentation on the future of the social web in general and IndieWeb in particular on <a href="http://www.foocafe.org/event/beyond-twitter-an-indieweb-future-for-social-media">March 23 at Foo Café</a> here in my hometown of Malmö.</p>
<p>I also hope to be able to attend some of the IndieWebCamps that are coming up, such as the <a href="https://indiewebcamp.com/2016/Nuremberg">Nuremburg</a> and <a href="https://indiewebcamp.com/2016/Germany">Düsseldorf</a> ones.</p>
<h3 id="next-part">Next part</h3>
<p>I’ll soon publish the remaining parts of this serious of four posts about my 2015.</p>
My 2015 in Startup2016-03-10T22:30:00+00:00http://voxpelli.com/2016/03/my-2015-in-startup<p>2016 is in full swing and it’s long overdue to take a look back at the past year and what happened then. This is part one of four in a series of posts about 2015.</p>
<h3 id="the-start">The start</h3>
<p>2015 started out in the startup world. I was still part of the <a href="http://www.bloglovin.com/">Bloglovin</a> and we were finally getting ready to launch some of the work of me and my closest colleagues.</p>
<h3 id="push-and-facebook-mimicking">Push and Facebook mimicking</h3>
<p>For me my first feature to launch was push notifications. When I first joined Bloglovin I was tasked with building the backend that handled our users’ notification subscriptions across all of their devices and ensuring that messages was routed correctly whenever any of our backends wanted to notify a user about something. We initially launched on iOS with follow notifications to try the systems out and then later on added notifications for new posts as well.</p>
<p>Next major feature of mine to launch was an improved metadata fetching for the blog posts. The platform featured a lot of gorgeus images and of course we wanted to present them the best way possible and I wanted to try and utilize the very same metadata that Facebook spearheaded sites to achieve that for us. That meant going beyond the metadata of the RSS feeds and pull down the actual blog posts, which were quite a few, and pull out that <a href="http://ogp.me/">open graph data</a> from them. Me and <a href="https://jacksoncage.se/">awesome devops Love</a> did a successful experiment with utilizing <a href="http://aws.amazon.com/lambda/">Amazon Lambda</a> to launch a fetching at that scale and amazingly saw it scale fairly easily to the full firehose of all new blog posts imported into Bloglovin (and that’s not few). Lambda really left an impression on me – it’s a cloud service that really deliveres on the promises of the cloud and is certainly something I want to return to in the future. After we have had the parser running for a while we also open sourced the very code behind it, <a href="https://github.com/bloglovin/metadataparser">metadata parser</a>, to make it easier for others to also make use of that same data so that all of us could have better metadata to show to our users.</p>
<p>While working on the metadata fetching project we also had a <a href="https://www.instagram.com/p/ygdrEwhfth/">great gathering</a> of the entire Bloglovin team in Stockholm where lots of amazing ideas were discussed – some truly inspirational days with great feedback and some great shout outs from members of the team. When working on a mostly remote team days like these are extra joyful.</p>
<h3 id="widgets-and-smart-feeds">Widgets and smart feeds</h3>
<p>With spring arriving two more projects came about to launch. First out was a new platform for <a href="http://www.bloglovin.com/widgets">interactive widgets</a>. I created a structure that enabled the creation of a bunch of new javascript widgets and first out to launch was two follow widgets – one where a user could follow a blog in a single click one and another one where they could follow through e-mail. All packaged up according to modern best practises for social media widgets and easily addable by bloggers to their blogs – a way to bridge the gap between Bloglovin the platform and the blogs of the blogosphere.</p>
<p>Then came the smart feed. Me and my colleague of the Malmö office, <a href="http://hugowetterberg.github.io/">Hugo</a>, were tasked with creating a new API endpoint that could weave additional kinds of content, eg. recommendations, into Bloglovin’s classic blog post feed. Through close cooperation with the iOS team and some great feedback from <a href="http://jaredsinclair.com/">Jared</a> and others we designed what I believe was a pretty solid and flexible API that could scale to most feature requirements and have lots of room for future experimentation – all while still remaning compatible with and presenting a good experience for all those who doesn’t update their apps the second a new version comes out. It was a great experience to have to design such a flexible API for an environment such as iOS with the different limitations it has compared to the web and the adaptions one have to make to accomodate for that, especially when it comes to supporting legacy versions of an application – something one can often avoid in regular web development work, perhaps to the harm of the API design of those.</p>
<h3 id="the-departure">The departure</h3>
<p>Then came summer and it became time for the Skåne team of Bloglovin to leave. Each one of us found we wanted to move on so as summer got closer and closer more and more of us left. For me it had become ever more apparent that me and Bloglovin had different visions on how to move ahead and I then felt it was best for us to part ways. So at the end of June I left the company and followed the example of <a href="http://simonljungberg.se/">Simon</a>, who had left just before, and started to freelance (Simon later on got an awesome opportunity to join <a href="http://www.filibaba.com/">Filibaba</a> where he’s now part of producing amazing vegetarian recipe apps – exciting stuffs!), while <a href="http://hugowetterberg.github.io/">Hugo</a> around the same time decided to join up with the local major newspaper <a href="http://hdsydsvenskan.se/">HD-Sydsvenskan</a> (where also he is creating some rather amazing, although so far less visible, stuff – Go-driven newspaper will be the thing of 2016!).</p>
<h3 id="next-part">Next part</h3>
<p>I’ll soon publish part two in this series of four post about my 2015 which will take a look at what happened in the IndieWeb world.</p>
My 2015 in Freelance2016-01-03T10:00:00+00:00http://voxpelli.com/2016/01/my-2015-in-freelance<p>2016 is in full swing and it’s long overdue to take a look back at the past year and what happened then. This is part two of four in a series of posts about 2015.</p>
<h3 id="the-start">The start</h3>
<p>Bloglovin and IndieWeb aside, after the funemployment of the summer the projects started to arrive in the autumn and now I’ve got plenty to do with lots of freelancing projects of a very varying nature and am gaining new experiences by the day and evaluating, planning and thinking about the upcoming year and what shape and in what direction I will take my freelancing then.</p>
<p>My latest project, which is still an ongoing one with many additions and tweaks to come, is the site for this year’s <a href="https://2016.theconference.se/">The Conference</a> which was created with Node.js, Heroku, Stripe, Sass, Browserify, some vanilla JS etc. and which sold a fourth of all of the tickets in <a href="http://8till5.se/2015/12/21/en-fjardedel-av-biljetterna-till-the-conference-slut-pa-tre-dagar/">just three days</a> without a hiccup and before any speakers had been announced. More tweaks will come and speakers and programs will be added.</p>
<p>As for this year it will start out by rejoining some former colleagues on an interesting Malmö based project until February and after that perhaps a new office at <a href="http://malmocoworking.se/">Malmö Coworking</a>. The plans are still not set for the rest of the spring and summer so there’s still a possibility to hire me for whatever crazy project or sweet creation one would want my help or input on. We can always grab a coffee and discuss the possibilities, so send me an email at <a href="mailto:[email protected]">[email protected]</a> if you think you have an interesting opportunity – tiny or large.</p>
<p>That’s 2015. Quite a lot happened there. And this is 2016. And even more will happen here. But to end things – here’s a full list of the open source projects of mine that I’ve created or updated during the year:</p>
2015 in review2016-01-03T10:00:00+00:00http://voxpelli.com/2016/01/2015-in-review<p>A new year has come and it’s time to say good bye to an eventful year by taking a look back at it.</p>
<h3 id="tldr">tl;dr</h3>
<p>The year started out at Bloglovin, but I later left and now I freelance. Throughout I built some cool stuff for both Bloglovin (push, better images, smarter feed) and the IndieWeb (publishing to Jekyll blogs from eg. iOS etc) and now I’m all occupied building cool stuff as a freelancer.</p>
<h3 id="startup">Startup</h3>
<p>2015 started out in the startup world. When it entered the scene I was still part of <a href="http://www.bloglovin.com/">Bloglovin</a> and we were getting ready to launch a lot of the stuff me and my closest colleagues had been working on.</p>
<p>My first feature to launch was push notifications, of which I was tasked with building the backend that was the middleman between devices that were to receive notifications and our other backends that wanted to notify a user about something.</p>
<p>Then the launches moved on to improved metadata fetching for blog posts – something which was to enable eg. better images on Bloglovin by utilizing the very same metadata that eg. Facebook uses. Me and the <a href="https://jacksoncage.se/">awesome devops Love</a> on this also did a successful experiment with Amazon Lambda and thus saw it scale to all of Bloglovins imported blog posts with ease – a cloud service that really delivered on the promises of the cloud and something I definitely want to return to in the future. Later on we also open sourced the very code behind the <a href="https://github.com/bloglovin/metadataparser">metadata parser</a>.</p>
<p>In the midst of the metadata fetching project we also had a terrific <a href="https://www.instagram.com/p/ygdrEwhfth/">gathering</a> of the entire Bloglovin team in Stockholm where lots of amazing ideas were discussed – some truly inspirational days.</p>
<p>When winter then turned spring and the summer started to approaching two other projects launched. First out was new interactive widgets – a platform that enabled the easy embedding of javascripts widgets on peoples own blogs so that one could eg. follow a blog on Bloglovin through a single click. After that came the smart feed that where I and <a href="http://hugowetterberg.github.io/">Hugo</a> of the Malmö office were tasked with creating a new API endpoint that could weave any kind of additional content or recommendations into the classic blog post feed. Through close cooperation with the iOS team and some great feedback from <a href="http://jaredsinclair.com/">Jared</a> and others we came up with a very solid and flexible API and backend that could scale to any feature requirements, leave the room open for lots of experimentation while still preserving good experience for all those weird people who doesn’t update their app the second a new version comes out. (Native apps and the challenges in pushing updates to code really puts a different perspective on backend development – and makes for some interesting situations and fun stories. A great experience to have.)</p>
<p>As summer arrived we all in the Skåne team of Bloglovin decided it was time to move on. For me Bloglovin wanted to move in a different direction than I did. After first having moved to a new apartment I followed the example of <a href="http://simonljungberg.se/">Simon</a> and decided to freelance (Simon later got the awesome opportunity to join <a href="http://www.filibaba.com/">Filibaba</a> where he now produces amazing apps with vegetarian recipes, while <a href="http://hugowetterberg.github.io/">Hugo</a> on the other hand went on to <a href="http://hdsydsvenskan.se/">HD-Sydsvenskan</a> where he apparently is also creating some rather amazing, although less visible, things).</p>
<h3 id="indieweb">IndieWeb</h3>
<p>So I left Bloglovin at the end of June and entered a few months of vacation/”funemployment” (following the example of the excellent <a href="https://medium.com/@chrismessina/funemployed-153b2e691a4e#.kytskxorc">Chris Messina</a>) while waiting for the Swedish business world to get back from vacation – and what better way to spend a ”funemployment” than to read books in the sun and code IndieWeb in the dark?</p>
<p>The months after Bloglovin saw some interesting IndieWeb experiments. I decided to finally tackle one of the major problems I’ve been having in the IndieWeb problem: The fact that my blog is a static GitHub Pages hosted Jekyll site – something that makes it hard to do all of the dynamic awesomeness of eg. <a href="http://indiewebcamp.com/micropub">Micropub</a>. The simple solution would be to just abandon the staticness, but I really like Jekyll and how it enables me to focus on just content and markup and nothing but that. I also solved <a href="http://voxpelli.com/2013/12/webmentions-for-static-pages/">WebMention for static sites</a> 1,5 years before so surely Micropub could also be solved?</p>
<p>I decided that it would be my summer project – enabling myself to publish to my static GitHub Pages hosted Jekyll blog through a Micropub API. And three open sourced modules later I had it up and running. Through the <a href="https://github.com/voxpelli/node-micropub-express">Micropub Express</a>, <a href="https://github.com/voxpelli/node-format-microformat">Format Microformat</a> and <a href="https://github.com/voxpelli/node-github-publish">GitHub Publish</a> modules and some minor glue in between the three I could publish posts to my blog through tools like <a href="http://ownyourgram.com/">OwnYourGram</a> and <a href="https://quill.p3k.io">Quill</a> and they would be presented in the appropriate way through some more <a href="https://github.com/voxpelli/voxpelli.github.com/blob/master/_includes/post.html">complex templating</a> in my blog and possibly presented in one of the two new lists on my site, <a href="http://voxpelli.com/links/">Links</a> and <a href="http://voxpelli.com/social/">Social</a>. I’ve yet to polish the glue and the templates so that those can be released separately as well though.</p>
<p>When I had the publishing part working I also wanted to find useful ways to publish to it and since the IndieWeb is all about <a href="https://indiewebcamp.com/selfdogfood">selfdogfeeding</a> I couldn’t resist trying to copy the <a href="https://www.macstories.net/ios/instapaper-launches-notes-bringing-annotations-to-articles/">Instapaper annotations flow</a> that <a href="https://twitter.com/viticci">Federico</a> of <a href="https://www.macstories.net/">MacStories</a> described for the <a href="http://omz-software.com/editorial/">Editorial app</a> in <a href="https://www.macstories.net/reviews/editorial-1-2-brings-powerful-new-text-editing-features-more-ios-automation/">two articles</a> – so I had to try to create a Micropub flow for the Editorial app as well – and I succeeded (that funemployment thing – very productive) although it’s still a bit rough.</p>
<p>A screencast of the Editorial flow for publishing Instapaper annotations to the <a href="http://voxpelli.com/links/">Links</a> section of my blog (sorry for the silent sound):</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/U7hUR7flTAY" frameborder="0" allowfullscreen=""></iframe>
<p>It uses the three Editorial workflows: <a href="http://www.editorial-workflows.com/workflow/5833229495959552/tO76Z7cIfTU">Micropub</a>, <a href="http://www.editorial-workflows.com/workflow/5227209878929408/JZrTPYnXAiY">IndieAuth</a> and optionally <a href="http://www.editorial-workflows.com/workflow/5300464841129984/cghZUwlSP2k">IndieAuth Deauthorize</a>.</p>
<p>I later extended it with more metadata + a <a href="https://workflow.is/workflows/581bf69b9cce48129bb2628a7ddea67f">Workflow.app workflow</a> and <a href="http://www.editorial-workflows.com/workflow/5272002294185984/FjNSs8nDyBs">Editorial workflow</a> for replying to posts from within a browser. Here’s an updated screencast showing that:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/CBPmSpD2jN4" frameborder="0" allowfullscreen=""></iframe>
<p>I also made a <a href="https://workflow.is/workflows/0f7b503f16ca4709a43a55e00b4c71b2">Workflow.app workflow</a> for publishing a bookmark with an optional quote from the selection on a page in a browser – it uses the same <a href="http://www.editorial-workflows.com/workflow/5272002294185984/FjNSs8nDyBs">IndieAction</a> Editorial workflow as the reply one did.</p>
<p>So, I can now publish to my static blog from iOS – that’s pretty cool – happy to have had time this year to overcome that obstacle.</p>
<p>Now my blog supports nearly all the aspects of an IndieWeb:ish site – all I want to add before I say that it is fully IndieWeb:ish is automatic WebMention <em>sending</em> (something that’s a bit problematic for static sites as there’s often a build delay between publishing something and it being published, which means one has to wait with the pinging until one knows something has been published successfully. I have some ideas on plans on that as well though – that’s in the same spirit as my other solutions – so 2016 will likely see that little last piece of the puzzle solved).</p>
<p>In other IndieWeb news during the year: Not only did I focus on the new Micropub-related projects, but I of course also released some updates to my <a href="http://webmention.herokuapp.com/">WebMentions project</a>. All changes can be found in the <a href="https://github.com/voxpelli/webpage-webmentions#changelog">changelog</a> or can be <a href="https://github.com/voxpelli/webpage-webmentions/releases.atom">subscribed to</a>, but to summarize the most major changes:</p>
<ul>
<li>At the very beginning of the year a new experimental embed, ”cutting-edge”, was introduced to allow for UI-additions and with it a <a href="http://indiewebcamp.com/facepile">facepile</a> for showing <a href="http://indiewebcamp.com/interactions">interactions</a> such as like and repost was introduced.</li>
<li>Basic support for updates as well as some deletes of mentions was introduced – this also happens in realtime in some of the embeds.</li>
<li>The <a href="https://github.com/voxpelli/node-pg-pubsub">PG Pubsub</a> module was extracted from the underlying realtime solution and <a href="http://voxpelli.com/2015/01/pubsub-with-postgres-and-node-js/">launched</a> as a separate module for any Postgres Pubsub needs. As part of that also <a href="https://github.com/voxpelli/node-promised-retry">Promised Retry</a> was launched to provide for a Promised based mechanism to ensure that one always receives a database connection when asking for one and that proper retries are made when the connection is lost or can’t be established.</li>
<li>The code responsible for ensuring that all web pages fetched as part of the endpoint are fetched ”politely” (rate limited) was extracted as <a href="https://github.com/voxpelli/node-fetch-politely">Fetch Politely</a> and extended with an optional robots.txt mechanism from my <a href="https://github.com/voxpelli/relspider">relspider</a> so that ultimately both projects + other similar projects can share the same basic mechanism. Also added an optional database backend to that module which introduced persistence of throttled items across instances for the WebMentions project which in turn made me relax the limit of how many throttled items the endpoint accepted before returning errors.</li>
<li>As with most of my projects I moved to iojs and then later Node.js 4.x and now 5.x to get newer features like Promises and arrow functions natively. I still don’t do eg. Babel, especially not server side.</li>
<li>In the later part of the year yet another embed solution was created – one which solved the <a href="https://indiewebcamp.com/curlability">curlability</a> problem of the original embeds by moving to progressively enhance an existing link (marked up with the experimental <em>”u-responses”</em> class) rather than inserting WebMentions straight into the page. This was a precursor to <a href="http://indiewebcamp.com/Salmentions">Salmentions</a> support. As part of the work I also moved the WebMention project to use my <a href="https://github.com/voxpelli/node-tema">Tema</a> theming engine as I then felt a need for a server side templating solution and I preferred to reuse the same solution as on my other projects and the themability features that comes with it adds some cool new possibilities.</li>
<li>Not yet released, but added a full <a href="http://indiewebcamp.com/Salmentions">Salmentions</a> flow that receives comments from downstream, presents them and repings them upstream. As part of this I yet again discovered the amazingness of Postgres by <a href="https://github.com/voxpelli/webpage-webmentions/blob/05012a5f400a98aa2c8e3079ccbebec84d6f080c/lib/classes/entries.js#L284">recursively fetching</a> an infinitely deep comment tree through the use of <a href="http://www.postgresql.org/docs/8.4/static/queries-with.html"><em>”WITH RECURSIVE”</em></a>. Also as part of this feature extended and moved the parsing mechanism to an <a href="https://github.com/voxpelli/metadataparser/">extendable fork</a> of the Bloglovin <a href="https://github.com/bloglovin/metadataparser">Metadataparser</a> module that I created previously in the year and extended it with Microformats parsing for this project. The current Salmentions implementation is a bit too optimistic though, it repings upstream no matter if a comment has changed or not which can probably even result in infinite repingings – so some kind of check whether a post has been updated or not, perhaps even a pessimistic such, remains before launch and is being tracked in <a href="https://github.com/voxpelli/webpage-webmentions/issues/21">#21</a>.</li>
<li>and throughout the year did bug fixes and improvements to the underlying system</li>
</ul>
<h3 id="freelancing">Freelancing</h3>
<p>Bloglovin and IndieWeb aside, after the funemployment of the summer the projects started to arrive in the autumn and now I’ve got plenty to do with lots of freelancing projects of a very varying nature and am gaining new experiences by the day and evaluating, planning and thinking about the upcoming year and what shape and in what direction I will take my freelancing then.</p>
<p>My latest project, which is still an ongoing one with many additions and tweaks to come, is the site for this year’s <a href="https://2016.theconference.se/">The Conference</a> which was created with Node.js, Heroku, Stripe, Sass, Browserify, some vanilla JS etc. and which sold a fourth of all of the tickets in <a href="http://8till5.se/2015/12/21/en-fjardedel-av-biljetterna-till-the-conference-slut-pa-tre-dagar/">just three days</a> without a hiccup and before any speakers had been announced. More tweaks will come and speakers and programs will be added.</p>
<p>As for this year it will start out by rejoining some former colleagues on an interesting Malmö based project until February and after that perhaps a new office at <a href="http://malmocoworking.se/">Malmö Coworking</a>. The plans are still not set for the rest of the spring and summer so there’s still a possibility to hire me for whatever crazy project or sweet creation one would want my help or input on. We can always grab a coffee and discuss the possibilities, so send me an email at <a href="mailto:[email protected]">[email protected]</a> if you think you have an interesting opportunity – tiny or large.</p>
<p>That’s 2015. Quite a lot happened there. And this is 2016. And even more will happen here. But to end things – here’s a full list of the open source projects of mine that I’ve created or updated during the year:</p>
<h3 id="a-list-of-all-new-projects-2015">A list of all new projects 2015</h3>
<ul>
<li><a href="https://github.com/bloglovin/metadataparser">Metadataparser</a> – Node.js module, Bloglovin-related of which I currently have a <a href="https://github.com/voxpelli/metadataparser/">personal fork</a></li>
<li><a href="https://github.com/voxpelli/node-promised-retry">Promised Retry</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-pg-pubsub">PG Pubsub</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-fetch-politely">Fetch Politely</a> – Node.js module</li>
<li><a href="https://github.com/voxpelli/node-micropub-express">Micropub Express</a> – Node.js module, IndieWeb-related</li>
<li><a href="https://github.com/voxpelli/node-format-microformat">Format Microformat</a> – Node.js module, IndieWeb-related</li>
<li><a href="https://github.com/voxpelli/node-github-publish">GitHub Publish</a> – Node.js module</li>
<li>and some other projects that I have yet to polish some more on as well as eg. the above mentioned workflows for Workflow.app and Editorial.app that isn’t really standalone projects of their own</li>
</ul>
<h3 id="a-list-of-updated-projects-2015">A list of updated projects 2015</h3>
<ul>
<li><a href="https://github.com/voxpelli/lintlovin">Lintlovin</a> – Node.js module, a personal fork of mine which is upgraded to eg. use ESLint</li>
<li><a href="https://webmention.herokuapp.com/">A WebMention Endpoint</a> – hosted service written in Node.js</li>
<li><a href="https://github.com/voxpelli/node-connect-pg-simple">Connect PG Simple</a> – Node.js module – probably my smallest and most popular project with certainly the highest amount of contributors (GitHub currently says <a href="https://github.com/voxpelli/node-connect-pg-simple/graphs/contributors">8 other persons</a> have contributed to it)</li>
<li>and some other projects as well as a <a href="https://github.com/issues?utf8=%E2%9C%93&q=author%3Avoxpelli+is%3Apr++created%3A2015-01-01..2015-12-31+">bunch of PR:s</a> that’s been contributed to a bunch of projects – such as <a href="https://github.com/maxogden/dependency-check">Dependency Check</a>.</li>
</ul>
People are made of color2015-07-04T10:15:00+00:00http://voxpelli.com/2015/07/people-are-made-of-color<p>There are plenty of perspectives on things in life. At first they all seem pretty shallow and simple – black and white to speak in terms of color – things are one way or another and that’s that.</p>
<p>Then we start to familiarize ourselves with these ways to look at life and we see the many shades of grey in-between. We see that there’s not simply just women or men in the world. There’s masculine women, feminine men and more. There’s not just extroverts and introverts either – there’s many variations in-between. Not just gay people or straight people but plenty of stops along the way.</p>
<p>So then we start to get a more rich look on life. It’s not just 0% or a 100%. Something can be 40% or 60%. So then we’re happy for a while that we understand the world and the people living in it. But then we see that those perspectives we have treated separately actually interacts with one another.</p>
<p>A thing in life is not just 40% that or 60% this. It’s both. The world is not just many shades of grey – the world is in color – it’s inhabited by people of the most crazy and beautiful tones of color. People that can’t be labeled by a simple perspective – that can’t be labeled by a simple number – that only can be labeled by the unique combinations of perspectives that make up their very own unique lives – their very own unique colors.</p>
<p>And that’s what’s so great about people. That people are complex individuals – not robots that’s all built alike. Rather than being possible to label in black and white we all bring our own rich perspectives to the situations that we are in.</p>
<p>This means people can’t be dealt with as simply “women” or “men”, “extroverts” or “introverts”, “gay” or “straight”. The only dignifying and respectful way to deal with a person is to recognize the true extent to which that person is made up of plenty of shades of plenty of perspectives – recognizing that they may not be very much like those others they at first might have looked a lot alike. By recognizing that we acknowledge them as true individuals. True individuals with truly individual needs and abilities. A person that has to be dealt with in its own unique way, with no quick fixes or shortcuts.</p>
<p>This to me is what equality and feminism is all about. Seeing people as the colorful selfs they are rather than as packages of black and white labels from which one can pick and choose and judge. Feminism and equality is all about you and me both recognizing each other as who we truly are – every day and every hour – trying to find the colors in a grey day-to-day world.</p>
<p>Equality, colors – rainbows, individuals – people are people and people are color – it’s important, it’s needed, it’s right.</p>
We should have co-maintainer best practises2015-04-05T14:20:00+00:00http://voxpelli.com/2015/04/co-maintainer-best-practises<p>Collaboration is one of the key aspects of open source. The collaboration though is often dependent on the maintainer being able to accept or deny a contribution and to give feedback on the next step.</p>
<p>Many have over the years rightfully <a href="http://felixge.de/2013/03/07/open-source-and-responsibility.html">voiced concerns</a> about this reliance on the single maintainer – what do we do when the maintainer no longer answers?</p>
<p>Drupal solved this by both making it easy to add co-maintainers, through clear <a href="https://www.drupal.org/node/363367">best practices for co-maintaining projects</a>, and by having <a href="https://www.drupal.org/node/251466">clear procedures</a> for handing abandoned projects over to new owners.</p>
<p>That has enabled Drupal to <a href="https://www.drupal.org/contribute/development#collaboration">push hard</a> for collaborating on existing projects rather than adding new duplicates, which is a stark contrast to eg. the WordPress and jQuery communities where duplication rather than collaboration sadly seems to be the norm. (How many carousel, Facebook share plugins and parallax scripts do the world really need?)</p>
<p>More open source projects, and especially so the Node.js/NPM one which already have a high level of collaboration, should follow Drupal in defining clear best practises for co-maintenance. Sure, <a href="http://felixge.de/2013/03/11/the-pull-request-hack.html">Felix Geisendörfer’s Pull Request Hack</a> goes a long way – but it would be fairer for everyone if the expectations were clear and well communicated up front. It would lower the threshold of participation even further.</p>
<p>Through such best practises more maintainers would probably dare to add co-maintainers to their projects and co-maintainers would hopefully dare to go even further in their contributions to a project or even dare to step up as a co-maintainer at all in the first place. And that’s where we should be heading – towards more and easier collaboration.</p>