Skip to content

Commit

Permalink
replace own dependency tracking with vue-reactivity
Browse files Browse the repository at this point in the history
  • Loading branch information
usu committed Sep 8, 2022
1 parent fc318c9 commit b222441
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 56 deletions.
17 changes: 0 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
},
"dependencies": {
"emittery": "^1.0.0",
"vue": "^3.2.38"
},
"devDependencies": {
Expand Down
9 changes: 2 additions & 7 deletions src/api/async.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { fetch } from "./apiMock.js";
import Emittery from "emittery";
import { reactive } from "vue";

// cache for actual resource data (in raw format as provided by the fetcher). 1 entry per known uri (either requested uri or detected in response)
const resourceCache = new Map();

// cache for loading promises. 1 entry per requested uri
const promiseCache = new Map();

// event system used to signal changes in individual resources
export const emitter = new Emittery();

/**
* public API
*/
Expand Down Expand Up @@ -86,12 +83,10 @@ async function fetchFromNetwork(uri) {
for (const [key, value] of Object.entries(apiResponse)) {
let resource = resourceCache.get(key);
if (!resource) {
resourceCache.set(key, (resource = {}));
resourceCache.set(key, (resource = reactive({})));
}

resource.data = value; // careful to not override complete cache item to not destroy linking from any other objects

emitter.emit("resourceUpdated", key); // signal update of resource
}

return resourceCache.get(uri);
Expand Down
33 changes: 2 additions & 31 deletions src/api/reactive.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { fetchResourceAsync, fetchRelationAsync, emitter } from "./async.js";
import { fetchResourceAsync, fetchRelationAsync } from "./async.js";

import { triggerRef, shallowRef } from "vue";
import { shallowRef } from "vue";

// cache for reactive object. 1 entry per requested path (=uri or =uri + relation path)
// Hence, 1 resource can have multiple entries if requested via different paths
// Equivalent to a LoadingResource/LoadingProxy
const reactiveCache = new Map();

// maps URIs to dependent reactive objects
const dependencyMap = new Map();

// register listener for resource updates
emitter.on("resourceUpdated", triggerReactive);

/**
* External API
*/
Expand All @@ -36,7 +30,6 @@ export function getRelationReactive(uri, relation) {
*/
async function fetchResourceAndUpdateReactive(uri, reactiveObject) {
const resource = await fetchResourceAsync(uri);
addDependency(uri, reactiveObject);

// replacing the complete value of a shallowRef is reactive
// however: if any data within resource changes, the reactivity system wouldn't know (manual trigger of reactivity needed)
Expand All @@ -45,7 +38,6 @@ async function fetchResourceAndUpdateReactive(uri, reactiveObject) {

async function fetchRelationAndUpdateReactive(uri, relation, reactiveObject) {
const resource = await fetchRelationAsync(uri, relation);
addDependency(resource.data._links.self, reactiveObject); // only here we know which resource was returned

// replacing the complete value of a shallowRef is reactive
// however: if any data within resource changes, the reactivity system wouldn't know (manual trigger of reactivity needed)
Expand All @@ -63,31 +55,10 @@ function getReactiveFromCache(cacheKey) {
return reactiveObject;
}

// if data at resource uri has changed --> trigger reactivity for all reactive object that point to this resource
function triggerReactive(uri) {
if (dependencyMap.has(uri)) {
dependencyMap.get(uri).forEach((reactiveObject) => {
triggerRef(reactiveObject);
});
}
}

function addDependency(uri, reactiveObject) {
let dependentObjects = dependencyMap.get(uri);
if (!dependentObjects) {
dependencyMap.set(uri, (dependentObjects = []));
}

dependentObjects.push(reactiveObject);
}

/**
* Support / debug API
*/
export function debugReactive() {
console.log("reactiveCache");
console.log(...reactiveCache);

console.log("dependencyMap");
console.log(...dependencyMap);
}

0 comments on commit b222441

Please sign in to comment.