Quantcast
Channel: Dream Devourer

Week in Review 46/2017

$
0
0

Monday

13th November

First proper day back at work. I have to say that the KIT days have been a great help over the last few months and made it a lot easier to jump back in. Although the welcome had me a bit puzzled - my desk was still a hot desk and there was some guy sitting in it and my mouse was gone (well, not my mouse, since it was one of the generic office mice, but still...). No hard feelings though ;)

Warhammer evening.

Daily Baby

Just one photo... #dailyBaby

A post shared by Joanna Walker (@yish83) on

Tuesday

14th November

Baby sensory.

Birthday lunch at Nando's.

Cover image research for a client.

Mortgage renewal meeting.

Daily Baby

One year old :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

15th November

Trip to the GP - turns out they had to move the jabs as they booked Zack too early.

Extra book fields and exception handling for the book import in WriterPA.

Daily Baby

Foxy, a new friend :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

16th November

Work day.

Draft covers for a client.

Daily Baby

And what if I push *this* button...? #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

17th November

Work day.

Finished the excellent book "Children of Time"
by Adrian Tchaikovsky.

Started work on a premade cover, then laptop battery died...

This invention removes salt from seawater.

Daily Baby

Hidden dragon, crouching tiger... Cat food here I come! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Saturday

18th November

Weekly update post.

Baby swimming class - a lot better today, Zack seemed happy the old teacher was back...

Finished the premade cover.

Daily Baby

Swimming time! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

19th November

Zack's birthday party. Great day and fun time with friends and family.

Daily Baby

You can have the cake in a minute! Tsk... Tsk... #dailyBaby

A post shared by Joanna Walker (@yish83) on


Week in Review 47/2017

$
0
0

Monday

20th November

Work day.

Last day of my mom and dad's stay, little family gathering in the evening.

Daily Baby

Cuddles with grandpa :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Tuesday

21st November

Baby sensory.

Editing a Christmas romance - 2 pages.

Webinar.

Man discovers intense backstory to the 'distracted boyfriend' meme. This is hilarious.

Daily Baby

Jumperoooooo! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

22nd November

Edited 8 pages.

Zack had a reaction to his jabs and an infection, he probably caught at the nursery.

The Last Iron Lung

Daily Baby

Can't stop smiling #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

23rd November

Work day.

Edited 3 pages.

App Time for Nap Time: The Parennials Are Here

Daily Baby

Self service #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

24th November

Work day. First time I was dropping off Zack at nursery myself (well, OH came too, but still had to deal with train schedules for work).

Zack had to be picked up from the nursery due to fever.

Daily Baby

Daddy & son

A post shared by Joanna Walker (@yish83) on

Saturday

25th November

Started work on the baby album. 4 pages done... 104 or so to go ;) I really should have started working on this earlier. Not likely I'm going to make it before the discount for the prints expires.

Daily Baby

Cleaning obsession :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

26th November

Baby album work.

Daily Baby

This is a book, Teddy. My favourite book. #dailyBaby #weeklyTeddy #babyVoiceover

A post shared by Joanna Walker (@yish83) on

Week in Review 48/2017

$
0
0

Monday

27th November

Work day.

Warhammer game night.

Album work.

Daily Baby

Move along now... Nothing to see here. I am totally not stealing the remote #dailyBaby #babyVoiceover

A post shared by Joanna Walker (@yish83) on

Tuesday

28th November

Album work.

Baby sensory with daddy.

Daily Baby

Me? Make a mess? Never! #dailyBaby #babyVoiceover

A post shared by Joanna Walker (@yish83) on

Wednesday

29th November

Soft play at the Parkside cafe.

Cover for a client.

Album work.

Daily Baby

Hat record: 5 min #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

30th November

Work day.

Album work.

Daily Baby

Self service #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

1st December

Work day.

Album work.

Advice From A 19 Year Old Girl & Software Developer

Daily Baby

Happy bedtime #dailyBaby

A post shared by Joanna Walker (@yish83) on

Saturday

2nd December

Album work.

To Be Honest, Having It All Kinda Sucks

Daily Baby

You're not getting my breadstick. #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

3rd December

Album work.

Weekly update posts - catching up on the backlog. All this photo album work meant I barely had any time left - turns out at this rate the challenge is to meet the Christmas order deadline so I can get these delivered...

Daily Baby

No hats! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Week in Review 49/2017

$
0
0

Monday

4th December

Work day.

Photo album work.

Daily Baby

Nighty, night... #dailyBaby

A post shared by Joanna Walker (@yish83) on

Tuesday

5th December

Baby sensory.

Album work.

Daily Baby

Sneak peek :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

6th December

Sky installation. Turns out the bad reception and missing signal on one cable had nothing to do with the renovations - the original cables were cut wrong and the outside bit had water coming in. All sorted now, what a relief to be able to record things again...

Album work.

Daily Baby

Escape artist #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

7th December

Work day.

Album work.

Daily Baby

Stomp! Stomp! Stomp! Here's my coat mommy. #dailyBaby #walking

A post shared by Joanna Walker (@yish83) on

Friday

8th December

Work day.

Zack had a fever, so had to pick him up early from the nursery.

Christmas meetup with dev friends.

I Made My Shed the Top Rated Restaurant On TripAdvisor

Daily Baby

Card from the nursery. #dailyBaby

A post shared by Joanna Walker (@yish83) on

Saturday

9th December

Album work.

Bitcoin and the millennials may have created a perfect storm

Daily Baby

Reading together #dailyBaby #reversed

A post shared by Joanna Walker (@yish83) on

Sunday

10th December

NCT Christmas meetup. It was really nice seeing people again. All the babies are so grown up now!

Album work - finished the layout of all the pages. Just editing and the cover left now.

Daily Baby

Unimpressed with Santa ;) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Week in Review 50/2017

$
0
0

Monday

11th December

Work day.

Evening meetup.

Album work.

This Comic Perfectly Explains the Struggle Moms Have With Work-Life Balance

Daily Baby

Off to the nursery we go #dailyBaby #earlyMorning

A post shared by Joanna Walker (@yish83) on

Tuesday

12th December

Baby sensory.

Christmas shopping.

Album work.

5 Early Signs Of Dementia (And Why Everyone Should Know Them)

Daily Baby

Baby sensory class - parachute AND bubbles together #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

13th December

Album work.

Building control visit.

First tooth and a not so happy baby Christmas at the nursery.

Cover draft for a client.

'Cards Against Humanity' Sends Checks To Their Lowest-Earning Customers And It's Bringing Attention To Wealth Inequality

An Ode to the Brilliance of Roguelikes Got a bit sentimental reading this article. Oh, the hours I spent playing ADOM...

Daily Baby

Even asleep he's not letting go of his bread stick #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

14th December

Work day.

Department Xmas party.

This is what work-life balance looks like at a company with 100% retention of moms

I Don’t Play With My Kids, Here’s Why

Daily Baby

Daddy's getting a helping hand #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

15th December

Work day.

Baby sick again.

Cover draft for a client.

Daily Baby

##Saturday *16th December*

Mini-Christmas with the in-laws.

Album work.

Cover draft for a client.

How An Episode Of 'Chopped Junior' Changed The Way I Parent

Daily Baby

Mini Christmas. The paper is the best bit! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

17th December

Packing and house cleaning.

Sorted the address change for one of the accounts.

Meetup with Kat & Agnes.

Flight to Poland.

Daily Baby

I'm all packed! Take me to granny! :-) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Week in Review 51/2017

$
0
0

Monday

18th December

Meetup with grandparents.

Finished cover for a client.

Album work.

Daily Baby

Car business... #dailyBaby

A post shared by Joanna Walker (@yish83) on

Tuesday

19th December

Album work.

Daily Baby

Running with a bowl #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

20th December

Album work.

An attempt to analyse a board game we just got in a Christmas cracker

GOOGLE MAPS’S MOAT

Daily Baby

The favourite toy... #dailyBaby #weeklyTeddy

A post shared by Joanna Walker (@yish83) on

Thursday

21st December

Trip to Poznan.

Daily Baby

Getting into the Christmas spirit :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

22nd December

Album work.

We went to the Aquapark in Poznan - the facilities are amazing: great areas for babies and kids with loads of toys, several slides, including my favourite multimedia ride and a pontoon one, and a collection of saunas.

The best board game of 2017 is a wildly entertaining romantic comedy generator

Daily Baby

Pickle! #dailyBaby

A post shared by Joanna Walker (@yish83) on

Saturday

23rd December

Poznan National Art Gallery.

Christmas shopping.

We went back home by train. Really impressed with the new main train station in Poznań.

Album work.

Daily Baby

Best toys ever #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

24th December

Christmas Eve with the family.

Tesla's giant battery bailed out a coal power station

Daily Baby

Santa's little helper :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Week in Review 52/2017

$
0
0

Monday

25th December

Album work.

Daily Baby

Ready to go out :) #dailyBaby

A post shared by Joanna Walker (@yish83) on

Tuesday

26th December

Album work.

Approved SMM articles.

Paid bills and nursery.

Daily Baby

First walk outside #dailyBaby

A post shared by Joanna Walker (@yish83) on

Wednesday

27th December

Album work.

Daily Baby

What have you got there? #dailyBaby

A post shared by Joanna Walker (@yish83) on

Thursday

28th December

Finished the photo album. Phew... Only took several weeks of constant work. sigh Don't think I'll be doing this again. Next one is being done in increments over the year (don't we all say that ha ha ha).

6 Waldorf-Inspired Principles Every Family Should Adopt

Daily Baby

Looking good in daddy's hat #dailyBaby

A post shared by Joanna Walker (@yish83) on

Friday

29th December

Finished the book import feature for WriterPA.

Something is wrong on the internet

Caitlin Moran: what young women really need to know

Ten years in, nobody has come up with a use for blockchain

Daily Baby

Garden walk #dailyBaby

A post shared by Joanna Walker (@yish83) on

Saturday

30th December

Frosty walk to Łabiszynek.

Weekly update posts - finally caught up. December has been crazy busy, so while I've been taking notes, haven't had time to add all the links and photos.

Daily Baby

Trying out more hats #dailyBaby

A post shared by Joanna Walker (@yish83) on

Sunday

31st December

Travel back home.

Daily Baby

2018 New Year Resolutions

$
0
0
2018 New Year Resolutions

Where has the year gone? It feels like I was just writing last year's post and here we are again. Even worse January is over before I got around to doing this write-up.

Weekly Updates

The weekly posts were an interesting experiment and have served at least partially their purpose motivating me to push a little bit harder. Especially on some days where it would have been all to easy to do nothing after an exhausting day with the baby or at work.

But at the same time I don't think the public format is working anymore. The links are on Facebook for my friends anyway, and so are the #dailyBaby photos...

The weekly posts also made me blog less. So I will try and do a proper post once a week from now on.

Reading

GoodReads 2017 Book Challange 33 out of 52 is still not a bad result, she said. Thanks to the baby taking up most of my time I've learned to embrace audio-books which definitely helped keep the count up.

It's been good to read more stories again (and not just research). Hoping to do even better this year.

The Obligatory Fitness New Year's Resolution

It wouldn't be January if I didn't try to get back on the wagon yet again. The first try lasted a week, then the diet killed the exercise and then I got sick which killed the diet. Ha ha ha. Well need to try a bit harder before January ends. Maybe it's time to bring out the kettle-bells from the garage...

Last year I was goaded into Whole30, which isn't really my thing, so this year it's back to lchf which, although hard to stick to at times, has always produced best results for me (not just in terms of weight loss but general well-being - the ghost of gestational diabetes ever present).

Productivity

I let myself go a bit in January. Outside of a few bits and pieces for clients I haven't really had a major project to focus on. Possibly due to the marathon of photo album creation through most of December (it was worth it in the end, but still...) a bit of passive tv entertainment was much needed (I will not get into my slight mobile game addiction here).

But as the month is drawing to an end and I'm settling back into a routine at the day job it's time to procrastinate a bit less in the evenings. The Valentine's Day book won't edit itself after all.

Last Year's Goals

This is the part were things get less rosy. Time to own up to a few shortcomings...

I haven't finished rewriting Dragon Scorned, writing Feral 2 or editing the romance stories lying in the drawer. I did publish 4 stories and a boxset though and a fifth story went into a shared boxset with other authors. So not a completely lost year. However with those numbers it's hard to speak of any momentum.

The Dragons vs Zombies project is still on hold at the moment. And a lot depends on how things turn out at work, so until I get a reply about my part time application it's hard to predict when this might finally see the light of day.

I did make some progress on WriterPA (formerly knows as Plot In Motion). With better focus I did get a start on the framework for the project, but unfortunately not being able to get several hours straight of free time has been cramping my style. Editing and writing is a lot easier than coding in short bursts of 30-90 minutes at random points in the day (read: baby nap).

The Plan for 2018

drumroll

In some ways I'm hoping for more-of-the-same, but will be adding some new challanges:

  • join the GoodReads book challenge again, 52 book goal like last year
  • note down daily events/achievements, but moving to pen & paper
  • cook more from scratch
  • exercise besides walking places
  • edit and publish The Valentine's Day romance
  • launch WriterPA
  • re-write & re-publish Dragon Scorned
  • finish writing & publish Feral 2
  • writer & publish Hellena: Origins
  • design at least one pre-made cover per week
  • write one blog post per week

Example of Sequelize Associations in FeathersJS

$
0
0
Example of Sequelize Associations in FeathersJS

I've been playing around with FeathersJS and one thing that has been hard to find is a concrete example of setting up Sequelize with related tables.

Here's an example of the users table referencing a user_statuses table using the new model.associate() syntax including populating the output of the users.find() endpoint with a hook.

Model setup

The user's model here is the basic file generated by @feathersjs/authentication with just the foreign key added and the relationship defined.

# src/models/user.model.js
# file generated using @feathers/cli

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function(app){
	const sequelizeClient = app.get('sequelizeClient');
	const users = sequelizeClient.define('users', {
		email: {
			type: DataTypes.STRING,
			allowNull: false,
			unique: true
		},
		password: {
			type: DataTypes.STRING,
			allowNull: false
		},
		statusId: {
			type: Sequelize.INTEGER,
			field: 'status_id'
		}

	}, {
		hooks: {
			beforeCount(options){
				options.raw = true;
			}
		},
	});

	users.associate = function(models){
		users.hasOne(models.userStatuses, {
			as: 'UserStatus',
			foreignKey: 'id'
		});
	};

	return users;
};

UserStatuses model - just the generated file. No changes really needed for this one way relationship.

# src/models/user-statuses.model.js
# file generated using @feathers/cli

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function(app){
	const sequelizeClient = app.get('sequelizeClient');
	const userStatuses = sequelizeClient.define('userStatuses', {
		name: {
			type: DataTypes.STRING
		}
	}, {
		hooks: {
			beforeCount(options){
				options.raw = true;
			}
		},
	});

	userStatuses.associate = function(models){
	};

	return userStatuses;
};

Populating the Relationship

The goal is to return the related table as part of a users.find() call. As a bare minimum you want to set two Sequelize params in a before hook: include (see Sequelize documentation for more details on this option) and raw:true (if you want a nested object rather than a flat structure).

# src/services/users/users.hooks.js
# file generated by @feathers/authentication

const {authenticate} = require('@feathersjs/authentication').hooks;
const {
	hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;

module.exports = {
	before: {
		all: [],
		find: [
                        authenticate('jwt'),
                        //
                        //      Quick & dirty example 
                        //
                        context => {
                                const sequelize = context.params.sequelize || {};
                                sequelize.raw = true;
                                sequelize.include = [
		        		{
			        		model: context.app.services['user-statuses'].Model,
				        	as: 'UserStatus'
				        }
			        ];
                                return context;
	        	},
                ],
		get: [authenticate('jwt')],
		create: [hashPassword()],
		update: [hashPassword(), authenticate('jwt')],
		patch: [hashPassword(), authenticate('jwt')],
		remove: [authenticate('jwt')]
	},

	after: {
		all: [
			// Make sure the password field is never sent to the client
			// Always must be the last hook
			protect('password')
		],
		find: [],
		get: [],
		create: [],
		update: [],
		patch: [],
		remove: []
	},

	error: {
		all: [],
		find: [],
		get: [],
		create: [],
		update: [],
		patch: [],
		remove: []
	}
};

As various models might make use of this functionality I've actually created a generic hook addAssociations(). It takes multiple models for the include option and looks up the model object for you based on a shorthand string. (I'm still looking at a good way of handling hyphens vs camelcase so excuse the mix of names in the example below)

# src/hooks/add-associations.js
# hook generated by @feathers/cli

module.exports = function(options = {}){
	options.models = options.models || [];

	return async context =>{
		const sequelize = context.params.sequelize || {};
		const include = sequelize.include || [];

		//	Reasign in case we created these properties
		sequelize.include = include.concat(options.models.map(model => {
			const newModel = {...model};

			newModel.model = context.app.services[model.model].Model;
			return newModel;
		}));

		//	Nested output
		sequelize.raw = false;

		context.params.sequelize = sequelize;
		return context;
	};
};

And here's the updated users.hooks.js file:

# src/services/users/users.hooks.js
# file generated by @feathers/authentication

const {authenticate} = require('@feathersjs/authentication').hooks;
const addAssociations = require('./../../hooks/add-associations');

const {
	hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;

module.exports = {
	before: {
		all: [],
		find: [
			authenticate('jwt'),
			addAssociations({
				models: [
					{
						model: 'user-statuses',
						as: 'UserStatus'
					}
				]
			})
		],
		get: [authenticate('jwt')],
		create: [hashPassword()],
		update: [hashPassword(), authenticate('jwt')],
		patch: [hashPassword(), authenticate('jwt')],
		remove: [authenticate('jwt')]
	},

	after: {
		all: [
			// Make sure the password field is never sent to the client
			// Always must be the last hook
			protect('password')
		],
		find: [],
		get: [],
		create: [],
		update: [],
		patch: [],
		remove: []
	},

	error: {
		all: [],
		find: [],
		get: [],
		create: [],
		update: [],
		patch: [],
		remove: []
	}
};

All this results in a nice nested JSON response:

{
    "total": 1,
    "limit": 10,
    "skip": 0,
    "data": [
        {
            "id": 1,
            "email": "name@example.com",
            "statusId": 1,
            "created_at": "2017-11-08T15:25:01.000Z",
            "updated_at": "2017-11-08T15:27:29.000Z",
            "UserStatus": {
                "id": 1,
                "name": "active",
                "created_at": "2017-11-08T15:25:01.000Z",
                "updated_at": "2017-11-08T15:25:01.000Z"
            }
        }
    ]
}

Git Gui Startup Error on Fedora

$
0
0

Recently started getting the following error when trying to run git gui. Googling the issue didn't seem to help much.

Error in startup script: bad pad value "2m": must be positive screen distance
    while executing
"grid $w.bitmap $w.msg -in $w.top -sticky news -padx 2m -pady 2m"
    (procedure "::tk::MessageBox" line 181)
    invoked from within
"::tk::MessageBox {*}$args"
    (procedure "tk_messageBox" line 2)
    invoked from within
"tk_messageBox -icon error -type ok -title {Git Gui (dev): error} -message {Spell checking is unavailable:

No word lists can be found for the language..."
    ("eval" body line 1)
    invoked from within
"eval $cmd"
    (procedure "error_popup" line 10)
    invoked from within
"error_popup [strcat [mc "Spell checking is unavailable"] ":\n\n$err"]"
    (procedure "_connect" line 28)
    invoked from within
"_connect $this $pipe_fd"
    (procedure "spellcheck::init" line 7)
    invoked from within
"spellcheck::init  $spell_fd  $ui_comm  $ui_comm_ctxm  "
    invoked from within
"if {[winfo exists $ui_comm]} {
	set GITGUI_BCK_exists [load_message GITGUI_BCK utf-8]

	# -- If both our backup and message files exist use the
	#    ..."
    (file "/usr/libexec/git-core/git-gui" line 3954)

At first I thought it's a tcl/tk issue, as related things kept popping up. However then I remembered I was having some dictionary issues not long ago that resulted in an annoying error pop-up from git gui (but it would still let me use the tool after dismissing the popup...).

I did find a fix for that one, but didn't get round to applying it on my home machine before a system update. And then the above happened.

It was only after reading through the whole message I noticed this line:

No word lists can be found for the language...

Oh... Could this really be the same issue?

Yep. And the fix is quite simple:

dnf install aspell-en or the language of your choice

SSH Broken Pipe When Running in VMWare Workstation

$
0
0

Another note to self post... since this bit me more than once.

ssh USER@SERVER
...
packet_write_wait: Connection to IP_ADDRESS port 22: Broken pipe

Most of the answers point to the ServerAliveInterval or ClientAliveInterval but if you are running the command from inside VMWare Workstation (broken for me in v14 and 15.0.0) chances are the setting you want is actually IPQoS:

# ~/.ssh/config
...
Host *
IPQoS lowdelay
...

2019 New Year Resolutions

$
0
0
2019 New Year Resolutions

Whoa! Is it January already?!

I guess it's time to check back on last year's post and setup some unrealistic expectations once again...

Last year's goals

Since I made a handy list last year I can easily check my level of fail. 😂

✔ join the GoodReads book challenge again, 52 book goal like last year

I joined, I read listened, made decent progress. I might have not reached the ambitious 52 books, but pretty happy with the 27 I ended up with.

🤦‍♀️ note down daily events/achievements, but moving to pen & paper

Okay, I did some note taking, but not as much as I planned. Definitely not daily. Though December has been quite good as I discovered Everyday - great, super simple app for tracking habits. I also started tracking my project work with Makerlog. It does mean I have less to note in the paper journal, but it always felt a bit odd to get down into techy details on paper.

✔ cook more from scratch

Okay, I'm not reaching Domestic Goddess™ levels here, but definitely did more than the year before. I've got a few staples now I can do in the slow cooker without having to consult a recipe. Still needs more work though...

❌ exercise besides walking places

This is a big fail. Ooops. Tried getting back into yoga and martial arts, but willpower reserves were a bit low and baby did not cooperate when I tried to incorporate him into a routine. 😂

❌ edit and publish The Valentine's Day romance

❌ re-write & re-publish Dragon Scorned

❌ finish writing & publish Feral 2

❌ writer & publish Hellena: Origins

Nope. Pretty much all of the writing & publishing goals got put on hold so I could focus on obtaining citizenship and WriterPA.

✔ launch WriterPA

Woo hoo! 🎉✨🎈 The app went live just as the year was coming to a close.

Yes WriterPA is only in alpha, yes, it's still full of bugs and missing features, BUT it is live and I will be adding first (test) users in January.

❌ design at least one pre-made cover per week

Another casualty of having a day job and on-problem-at-a-time approach to side-projects...

❌ write one blog post per week

Given there's only two posts between this and last year's New Year's resolutions 😂 I haven't done so well, but that's more than 0.

Last Year Overview

I've touched on some things in the goal dissection above, but as usual I've been a tiny bit overoptimistic at the beginning of the year.

Going back to work forced me to rethink some things. After a year on maternity leave returning to work part time has been the best of both worlds. I have time with my son and am able to continue working which is great both socially and financially. But squeezing in writing and publishing projects between work and parenting proved a nearly impossible task. So something had to give, especially when I still wanted to spend time playing D&D on a nearly weekly basis...

But I did get some big milestones in. I've now successfully completed the UK citizenship application. Brexit is still shit, but at least it's one less direct worry once I get my passport. And I've already mentioned WriterPA going live.

We had an amazing family holiday abroad thanks to my sister's awesome organizing skills. My parents got to spend lots of time with their grandson and enjoy their first holiday in years. Unfortunately with my grandfather's health deteriorating near the end of the year we might not be able to repeat the adventure this year 😢

Speaking of adventures we started a new campaign in Eonika (a homebrew tabletop rpg system). And so far each session has been better than the previous one.

I've also dipped my toe into two communities: Twitch and Women Make. So far I've mostly been watching streams in Science&Technology, but I'm slowly building up courage to stream some coding myself. When it comes to the maker community, like Women Make, I'm still struggling with a bit of an impostor syndrome. After all it only took me like 7 years to ship WriterPA 😂 But I do make book covers a bit more often that that, so there's that...

What's Next?

As is tradition here's some outrageous goals for 2019:

  • lead a more balanced life (sleep more, work less)
  • join the GoodReads book challenge again, 52 book goal like last year
  • exercise besides walking places
  • 30 paying clients for WriterPA
  • launch Cobundle
  • lose 12kg
  • publish Vampires on the Train anthology
  • re-write & re-publish Dragon Scorned
  • finish writing & publish Feral 2
  • create a plan of action for the recipe site

FeathersJS Sequelize Soft Delete

$
0
0

It might have been the late hour but spent over 1.5h chasing this the other day... and getting tangled up in config and softdelete2 feathers-plus hooks.

Turns out to setup soft deletes in FeathersJS using feathers-sequelize you only need the Sequelize built in paranoid option.

Here's the example that makes it clear.

sequelizeClient.define('exampleTable', {
	id: {
		type: DataTypes.BIGINT(20).UNSIGNED,
		primaryKey: true,
		autoIncrement: true,
	},
	...
}, {
	tableName: 'example_table',
	paranoid: true,
	deletedAt: 'deleted_at'
});

In essence:

  • no need to define a field for deleted_at
  • add the paranoid: true option to your sequelize model
  • add the field name deletedAt: 'deleted_at' option to your sequelize model (if using alt name)
  • sequelize model option timestamps: true should be set, though it is the default, so you likely won't need to declare it

If you need a query that includes the soft deleted items set paranoid: false in a hook.

context => {
	context.params.sequelize = {paranoid: false};
}

Any includes will need their paranoid flag set:

context => {
	context.params.sequelize = {
		include: [{
			model: SomeModel,
			paranoid: false
		}], 
		paranoid: false
	};
}

Create React App Fix for Webpack Symlinks Without Ejecting

$
0
0

When restructuring my project and moving it to use Create React App I've ended up with an odd error for my shared jsx components (I've split the project into two separate apps but some of the styling and UI components will be the same so didn't want to duplicate code.)

./_shared/components/Spinner.jsx 21:2
Module parse failed: Unexpected token (21:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

I spent some time figuring out why this file refused to work while other components used the .jsx extension and did not throw errors. Eventually looking at issues with the same error I realized it was the symlinks causing problems. I had to symlink _shared as CRA does not allow modules outside src...

Now for the solution. Webpack has a config option webpack.resolve.symlinks that fixes the issue above.

But with a CRA you can't edit webpack config directly. I didn't want to eject - since the whole point of moving to CRA was to not have to deal with config discrepancies (or at least deal with them less). I already use craco for handling less and antd, so only needed to add the webpack section as below.

/* craco.config.js */
module.exports = {
	// ...
	webpack: {
		configure: {
			resolve: {
				symlinks: false,
			},
		},
	},
};

Cross Subdomain Authentication with FeathersJS Client

$
0
0

FeathersJS v4 switched from storing the jwt token in a cookie to localStorage. This was fine when the app stayed on one domain, but when splitting things out into several apps on different subdomains I realised unlike cookies localStorage does not play nicely.

I found the Customization option in the documentation which looked promising, but for some reason using the example gave me:

TypeError: Class constructor AuthenticationClient cannot be invoked without 'new'

Not wanting to go down the rabbit hole of config issues with yarn workspaces + Create React App a bit of a dirty workaround:

import auth from "@feathersjs/authentication-client";

const MyAuthenticationClient = auth.AuthenticationClient;

//  Keep the original method as we will need to call it
MyAuthenticationClient.prototype.parentGetFromLocation =
    MyAuthenticationClient.prototype.getFromLocation;

MyAuthenticationClient.prototype.getFromLocation = function (location) {
    //  getCookie() - function to retrieve the jwt content from the cookie
    location.hash = "access_token=" + getCookie("MY_COOKIE_NAME");
    return this.parentGetFromLocation(location);
};

feathersAPI.configure(
  auth({
    Authentication: MyAuthenticationClient,
    storage: localStorage,
  })
);

This will make the jwt token stored in the parent domain cookie available during authentication. You just need to make sure the cookie is saved during the login process.






Latest Images