Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
janwerkhoven committed Jan 27, 2024
1 parent abc9084 commit 8f9a7bb
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
3 changes: 3 additions & 0 deletions app/pods/application/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import { hash } from 'rsvp';
export default class ApplicationRoute extends BaseRoute {
beforeModel() {
super.activate();

this.page.update({
id: 'application-loading',
title: 'Loading ...',
showLoading: true,
origin: this.routeName
});

this.visit.create();
}

model() {
Expand Down
8 changes: 5 additions & 3 deletions app/pods/base/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ export default class BaseRoute extends Route {
// These services are available to all routes which inherit BaseRoute.
@service api; // Knows how to talk to the backend.
@service auth; // Manages user authentication.
@service cache;
@service cache; // For caching data and prevent reloads.
@service fastboot; // Ember's pre-serve renderer.
@service headData; // Controls the <head> meta tags.
@service header;
@service header; // To allow routes to make changes to request headers.
@service modal; // For controlling the <Modal> component.
@service page; // For controlling the <Page> component.
@service router; // Ember's route service.
@service seo; // For SEO concerns
@service store; // Ember's data store.
@service translation;
@service window;
@service uuid; // For generating UUIDs.
@service visit; // For anything related to visitors.
@service window; // Shadow methods to prevent Node (Fastboot) from blowing up.

@tracked cachedPayload;

Expand Down
17 changes: 17 additions & 0 deletions app/services/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {

export default class ApiService extends Service {
@service auth;
@service fastboot;
@service visit;

// Where the API lives
// In production: https://rails.api.interflux.com
Expand Down Expand Up @@ -46,6 +48,21 @@ export default class ApiService extends Service {
// expect back from the API is JSON API compliant data.
headers['Accept'] = 'application/vnd.api+json';

// Each request will send up the Visit UUID so that subsequent request can
// be grouped. This is unique to this project, thus the X namespace.
headers['Visit-ID'] = this.visit.id;

// Add visit metadata to the requests.
if (this.fastboot.isFastBoot) {
const request = this.fastboot.request;
headers['SSR-Host'] = request.host;
headers['SSR-Referer'] = request.headers.headers['referer'].join(',');
headers['SSR-User-Agent'] = request.headers.headers['user-agent'][0];
} else {
headers['Browser-Width'] = window.innerWidth;
headers['Browser-Height'] = window.innerHeight;
}

return headers;
}

Expand Down
31 changes: 31 additions & 0 deletions app/services/uuid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Service from '@ember/service';
import { inject as service } from '@ember/service';

export default class UuidService extends Service {
@service fastboot;

// Generates UUID v4
// Inspired from:
// https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
generate() {
let d = new Date().getTime();
let d2 =
(typeof performance !== 'undefined' &&
performance.now &&
performance.now() * 1000) ||
0;
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
let r = Math.random() * 16;

if (d > 0) {
r = (d + r) % 16 | 0;
d = Math.floor(d / 16);
} else {
r = (d2 + r) % 16 | 0;
d2 = Math.floor(d2 / 16);
}

return (c == 'x' ? r : (r & 0x7) | 0x8).toString(16);
});
}
}
38 changes: 38 additions & 0 deletions app/services/visit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Service from '@ember/service';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';

export default class VisitService extends Service {
@service fastboot;
@service uuid;

// A unique UUID given to this website session. It will:
// * be remembered across all Ember routes.
// * added to all requests coming from Ember.
// * help group requests for analytics
@tracked id;

create() {
if (this.fastboot.isFastBoot) {
// 1. Fastboot creates a unique UUID for this visit.
this.id = this.uuid.generate();

// 2. Fastboot passes this ID down to Ember.
this.fastboot.shoebox.put('visit', this.id);
console.log('🧩 fastboot created visit', this.id);
} else {
// 3. Ember retrieves the ID passed down from Fastboot.
const id = this.fastboot.shoebox.retrieve('visit');

if (id) {
// 4. Ember remembers ID for all requests going forward.
this.id = id;
console.log('🧩 ember found ID in shoebox', this.id);
} else {
// 5. If anything went wrong with Fastboot, create a UUID with Ember.
this.id = this.uuid.generate();
console.log('🧩 ember created visit 🔥🔥🔥', this.id);
}
}
}
}

0 comments on commit 8f9a7bb

Please sign in to comment.