gatsby-source-wordpress
Version:
Source data from WordPress in an efficient and scalable way.
320 lines (311 loc) • 9.55 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.shouldHardCacheData = exports.setPersistentCache = exports.setHardCachedNodes = exports.setHardCachedData = exports.restoreStaticDirectory = exports.restoreHardCachedNodes = exports.getPersistentCache = exports.getHardCachedNodes = exports.getHardCachedData = exports.getCacheInstance = exports.default = exports.clearHardCachedNodes = exports.clearHardCache = void 0;
var _cacheManager = _interopRequireDefault(require("cache-manager"));
var _fsExtra = _interopRequireDefault(require("fs-extra"));
var _cacheManagerFsHash = _interopRequireDefault(require("cache-manager-fs-hash"));
var _path = _interopRequireDefault(require("path"));
var _rimraf = _interopRequireDefault(require("rimraf"));
var _store = require("../store");
var _getGatsbyApi = require("./get-gatsby-api");
var _fetchGraphql = _interopRequireDefault(require("./fetch-graphql"));
var _helpers = require("../steps/create-schema-customization/helpers");
var _fetchReferencedMediaItems = require("../steps/source-nodes/fetch-nodes/fetch-referenced-media-items");
const MAX_CACHE_SIZE = 250;
const TTL = Number.MAX_SAFE_INTEGER;
const cacheDir = `.wordpress-cache/caches`;
class Cache {
constructor({
name = `db`,
store = _cacheManagerFsHash.default
} = {}) {
this.store = void 0;
this.name = void 0;
this.cacheDirectory = void 0;
this.cache = void 0;
this.name = name;
this.store = store;
this.cacheDirectory = cacheDir;
}
get cacheBase() {
return _path.default.join(process.cwd(), this.cacheDirectory);
}
get directory() {
return `${this.cacheBase}/${this.name}`;
}
init() {
_fsExtra.default.ensureDirSync(this.directory);
const configs = [{
store: `memory`,
max: MAX_CACHE_SIZE,
ttl: TTL
}, {
store: this.store,
ttl: TTL,
options: {
path: this.directory,
ttl: TTL
}
}];
const caches = configs.map(cache => _cacheManager.default.caching(cache));
this.cache = _cacheManager.default.multiCaching(caches);
return this;
}
get(key) {
return new Promise(resolve => {
if (!this.cache) {
throw new Error(`Cache wasn't initialised yet, please run the init method first`);
}
this.cache.get(key, (err, res) => {
resolve(err ? undefined : res);
});
});
}
set(key, value, args = {
ttl: TTL
}) {
return new Promise(resolve => {
if (!this.cache) {
throw new Error(`Cache wasn't initialised yet, please run the init method first`);
}
this.cache.set(key, value, args, err => {
resolve(err ? undefined : value);
});
});
}
}
exports.default = Cache;
const caches = new Map();
const getCacheInstance = name => {
let cache = caches.get(name);
if (!cache) {
cache = new Cache({
name
}).init();
caches.set(name, cache);
}
return cache;
};
exports.getCacheInstance = getCacheInstance;
const shouldHardCacheData = () => {
const isDevelop = process.env.NODE_ENV === `development`;
if (!isDevelop) {
return false;
}
const {
pluginOptions: {
develop: {
hardCacheData
}
}
} = (0, _store.getStore)().getState().gatsbyApi;
return hardCacheData;
};
exports.shouldHardCacheData = shouldHardCacheData;
const setHardCachedData = async ({
key,
value
}) => {
if (!shouldHardCacheData()) {
return;
}
const hardCache = getCacheInstance((0, _store.withPluginKey)(`wordpress-data`));
await hardCache.set(key, value);
};
exports.setHardCachedData = setHardCachedData;
const getHardCachedData = async ({
key
}) => {
if (!shouldHardCacheData()) {
return null;
}
const hardCache = getCacheInstance((0, _store.withPluginKey)(`wordpress-data`));
const data = await hardCache.get(key);
return data;
};
exports.getHardCachedData = getHardCachedData;
const getHardCachedNodes = async () => {
const allWpNodes = await getHardCachedData({
key: `allWpNodes`
});
const shouldUseHardDataCache = allWpNodes === null || allWpNodes === void 0 ? void 0 : allWpNodes.length;
if (shouldUseHardDataCache) {
return allWpNodes;
}
return null;
};
exports.getHardCachedNodes = getHardCachedNodes;
const staticFileCacheDirectory = `${process.cwd()}/.wordpress-cache/caches/public/static`;
const staticFileDirectory = `${process.cwd()}/public/static`;
const restoreStaticDirectory = async () => {
await _fsExtra.default.copy(staticFileCacheDirectory, staticFileDirectory);
};
exports.restoreStaticDirectory = restoreStaticDirectory;
const copyStaticDirectory = async () => {
await _fsExtra.default.copy(staticFileDirectory, staticFileCacheDirectory);
};
const setHardCachedNodes = async ({
helpers
}) => {
if (!shouldHardCacheData()) {
return;
}
const allNodes = await helpers.getNodes();
const allWpNodes = allNodes.filter(node => node.internal.owner === `gatsby-source-wordpress`);
await setHardCachedData({
key: `allWpNodes`,
value: allWpNodes
});
// if we're hard caching data,
// that means any inline html images paths will be baked into
// the processed hard cached nodes.
// so we need to copy the static directory
await copyStaticDirectory();
};
exports.setHardCachedNodes = setHardCachedNodes;
const clearHardCache = async () => {
await new Promise(resolve => {
const directory = new Cache().cacheBase;
(0, _rimraf.default)(directory, resolve);
});
};
exports.clearHardCache = clearHardCache;
const clearHardCachedNodes = async () => {
const hardCachedNodes = !!(await getHardCachedNodes());
if (hardCachedNodes) {
await setHardCachedData({
key: `allWpNodes`,
value: null
});
}
};
// persistent cache
exports.clearHardCachedNodes = clearHardCachedNodes;
const setPersistentCache = async ({
key,
value
}) => {
const {
helpers
} = (0, _getGatsbyApi.getGatsbyApi)();
await Promise.all([
// set Gatsby cache
helpers.cache.set((0, _store.withPluginKey)(key), value),
// and hard cache
setHardCachedData({
key,
value
})]);
};
exports.setPersistentCache = setPersistentCache;
const getPersistentCache = async ({
key
}) => {
const {
helpers
} = (0, _getGatsbyApi.getGatsbyApi)();
const cachedData = await helpers.cache.get((0, _store.withPluginKey)(key));
if (cachedData) {
return cachedData;
}
const hardCachedData = await getHardCachedData({
key
});
return hardCachedData;
};
exports.getPersistentCache = getPersistentCache;
const restoreHardCachedNodes = async ({
hardCachedNodes
}) => {
const loggerTypeCounts = {};
const {
helpers,
pluginOptions
} = (0, _getGatsbyApi.getGatsbyApi)();
const {
reporter
} = helpers;
// restore nodes
await Promise.all(hardCachedNodes.map(async node => {
var _typeSettingsCache;
if (!loggerTypeCounts[node.internal.type]) {
loggerTypeCounts[node.internal.type] = 0;
}
loggerTypeCounts[node.internal.type] += 1;
// media items are created in a special way
if (node.internal.type.endsWith(`MediaItem`)) {
delete node.internal;
const {
createContentDigest,
actions
} = helpers;
return (0, _fetchReferencedMediaItems.createMediaItemNode)({
node,
helpers,
createContentDigest,
actions,
parentName: `Hard cache restoration`
// referencedMediaItemNodeIds,
// allMediaItemNodes = [],
});
}
node.internal = {
contentDigest: node.internal.contentDigest,
type: node.internal.type
};
const typeSettingsCache = {};
const typeSettings = // TODO: extend node type for wordpress?
(_typeSettingsCache = typeSettingsCache[node.type]) !== null && _typeSettingsCache !== void 0 ? _typeSettingsCache : (0, _helpers.getTypeSettingsByType)({
name: node.type
});
let remoteNode = node;
if (typeSettings.beforeChangeNode && typeof typeSettings.beforeChangeNode === `function`) {
const {
// additionalNodeIds: receivedAdditionalNodeIds,
remoteNode: receivedRemoteNode
// cancelUpdate: receivedCancelUpdate,
} = (await typeSettings.beforeChangeNode({
actionType: `CREATE_ALL`,
remoteNode,
actions: helpers.actions,
helpers,
fetchGraphql: _fetchGraphql.default,
typeSettings,
buildTypeName: _helpers.buildTypeName,
type: node.type,
wpStore: (0, _store.getStore)()
})) || {};
if (receivedRemoteNode) {
remoteNode = receivedRemoteNode;
}
}
// restore each node
// TODO: update gatsby types
await helpers.actions.createNode(remoteNode);
return null;
}));
Object.entries(loggerTypeCounts).forEach(([typeName, count]) => {
(0, _store.getStore)().dispatch.logger.createActivityTimer({
typeName,
pluginOptions,
reporter
});
(0, _store.getStore)().dispatch.logger.incrementActivityTimer({
typeName,
by: count,
action: `restored`
});
(0, _store.getStore)().dispatch.logger.stopActivityTimer({
typeName,
action: `restored`
});
});
// restore static directory
await restoreStaticDirectory();
// build createdNodeIds id array to be cached 1 level above
const createdNodeIds = hardCachedNodes.map(node => node.id);
return createdNodeIds;
};
exports.restoreHardCachedNodes = restoreHardCachedNodes;
//# sourceMappingURL=cache.js.map